电子产业一站式赋能平台

PCB联盟网

搜索
查看: 11|回复: 0
收起左侧

【犄角旮旯的bug】子类继承时声明了父类同名变量

[复制链接]
匿名  发表于 昨天 12:03 |阅读模式
很久没有更这个系列了,因为最近也没啥出bug的机会,所以这次的案例是之前一个朋友在群里的问题,很有意思所以分享一下。原问题中不涉及到项目内容和代码,所以就放心大胆的在这里放一下:请教网友一个问题,定义了一个父类一个子类,除了一个function重名但内容不同,父类子类定义了完全相同的成员变量和其他的function,然后环境用了set type override type,最后仿真发现子类那个不同的function用到的成员变量并不是自己传进去的,好像来自父类,并且是随机值,这个bug怎么解释
虽然直觉问题应该出在“virtual,父类句柄调用,factory没生效,没初始化或者没加this”这几件事上,但没觉得这个操作有什么问题,直到群里有人说了遇到的类似问题:我也遇到过,总结就是子类中不要声明和父类里同名的变量
这才发现,他说的是“定义了完全相同的成员变量”不是有“完全相同的成员变量”。好,那很明显问题就出现在子类继承时声明了父类同名变量这件事上。来,请ds给我们讲一下:变量隐藏(Variable Hiding):如果子类声明了与父类 同名且同类型 的成员变量,父类的变量会被隐藏(但依然存在)。此时,子类的方法中直接使用变量名时,默认访问的是 子类自己的变量,但如果子类未正确初始化这些变量,或者父类变量被意外访问,可能导致数据不一致。
很清楚,也就是说子类中声明了一个父类中已经存在的成员变量AA,那么父类中的该变量依旧存在(近似处于隐藏状态),即当前子类空间中可以视为有两个AA,如果父类变量被意外访问那么可能会出意料之外的事。什么时候父类成员会被访问呢?关于这个事欢迎访问之前一个系列的文章《【system verilog】OOP属性下的构造函数new,虚方法virtual和cast方法》。不访问也没啥关系,反正有一个场景是很明确的(也就是问题中涉及到的):父类句柄指向子类空间时,访问不带virtual的成员,会返回父类的结果。关于function/task在上面那个系列里说很多了,那我们看成员变量。看这个代码:
  • class father;  int AA = 1000;endclassclass ext extends father;  int AA = 2000;endclass...//env  father fa;  ext    ex;...  fa = ext::new();  ex = ext::new();  $display("fa.AA = %0d", fa.AA);  $display("ex.AA = %0d", ex.AA);打印结果:

    改成:
  • class father;  int AA;  function new();    AA = 1000;  endfunctionendclassclass ext extends father;  int AA;  function new();    super.new(); //这个super写不写都行,避免争执还是写上吧    AA = 2000;  endfunctionendclass...//env  father fa;  ext    ex;...  fa = ext::new();  ex = ext::new();  $display("fa.AA = %0d", fa.AA);  $display("ex.AA = %0d", ex.AA);打印结果:

    而如果注释掉子类中同名变量AA的重新声明,改成这样:
  • class father;  int AA;  function new();    AA = 1000;  endfunctionendclassclass ext extends father;  //int AA;  function new();    super.new(); //这个super写不写都行,避免争执还是写上吧    AA = 2000;  endfunctionendclass...//env  father fa;  ext    ex;...  fa = ext::new();  ex = ext::new();  $display("fa.AA = %0d", fa.AA);  $display("ex.AA = %0d", ex.AA);就不存在问题了:

    好,这个问题的复现和验证就完成了。我一直以为OOP这个系列已经可以终章了,没想到还能再补充一篇,过两天补过去吧,还是那句话,多交流多讨论总归是没有亏吃的。


    系列文章入口
    【芯片设计】SoC 101(一):绪论【芯片设计】FIFO漫谈(零)从无处不在的FIFO开始说起【芯片设计】计算机体系结构(一)虚拟内存【芯片设计】深入理解AMBA总线(零)绪论
    【芯片设计】握手协议的介绍与时序说明【芯片设计】复位那些小事 —— 复位消抖【芯片设计】快速入门数字芯片设计(一)Introduction【芯片验证】UVM源码计划(零)下定决心读源码前的自测环节
    【芯片设计】异步电路碎碎念(一) 到底什么是异步电路
    【芯片设计】从RTL到GDS(一):Introduction
    【芯片设计】系统中的可维可测状态记录寄存器设计
    其他文章链接
    【芯片验证】sva_assertion: 15道助力飞升的断言练习【芯片验证】可能是RTL定向验证的巅峰之作【芯片验证】RTL仿真中X态行为的传播 —— 从xprop说起【芯片验证】年轻人的第一个systemVerilog验证环境全工程与解析
    【芯片设计】verilog中有符号数和无符号数的本质探究
    【芯片设计】论RTL中always语法的消失术
    【芯片设计】代码即注释,注释即代码
    【芯片设计】700行代码的risc处理器你确实不能要求太多了
    入职芯片开发部门后,每天摸鱼之外的时间我们要做些什么呢
    如何计算系统的outstanding 和 burst length?
    芯片搬砖日常·逼死强迫症的关键词不对齐事件
    熟人社会里,一群没有社会价值的局外人
  • 本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    回复

    使用道具

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表