zoukankan      html  css  js  c++  java
  • 结构体类型重声明导致的bug一个

    bug前提条件

    当模块比較多。头文件较多,某个结构体类型会在当前模块中又一次声明进而引用其成员,而不直接包括其它模块的头文件。

    这种优点是不引入不须要的类型声明到此模块。头文件包括的交叉;坏处是,添加了bug的几率,耦合太大!比方以下一种情况发生而导致bug:

    已知两个模块A和B。同一个结构类型struct node在两个模块中分别声明。当中B模块无意或者有意调整了结构类型中的某些域。那么这个时候。若B模块中引用A模块中此类型实例然后訪问成员变量,就会引发bug!

    例如以下重现演示样例

    bug重现演示样例代码

    moduleA.c

    #include <stdio.h>
    struct node{
    	char *name;
    	void *data;
    };
    
    //定义測试变量
    struct node new = {
    	"TuoLuoFuSiJi",
    	NULL
    };
    
    //測试输出
    extern test_output(void);
    void output(void)
    {
    	printf("%s
    ", new.name);	
    }
    
    int main(int argc, char *argv[])
    {
    	printf("call output:
    ");
    	output();
    	printf("call test_output:
    ");
    	test_output();
    	return 0;
    }

    moudleB.c

    #include <stdio.h>
    //这里又一次声明,调整域的顺序
    struct node{
    	void *data;
    	char *name;
    };
    
    //引用moduleA中的new实例
    extern struct node new;
    
    void test_output(void)
    {
    	if(new.name)
    		printf("%s
    ", new.name);	
    	else
    		printf("name is null
    ");
    }
    
    Makefile

    run: moduleA.o moduleB.o
    	cc -o run moduleA.o moduleB.o

    运行结果:


    结果分析:

    在模块B中,对name的訪问偏移量计算是根据本模块中的声明决定的。name的偏移量是4!

    同理。在模块A中,name的偏移量是0.在模块B中訪问模块A中实例new时,

    依照偏移量4计算。得到的确是data的值。显然为NULL。

    解决的方法:

    建议办法

    1-往上提升;公共的类型声明。定义成一个全局性的头文件,多个模块共同使用。而不隶属与不论什么一方,避免交织

    2-合作协商;两个模块的绝对一致。即一方改变(比方增删成员。或者改域名),必须通知还有一方

    3-模块接口化。假设外面模块须要訪问本模块的实例。那么本模块应该提供接口。而不是让其它模块直接訪问自己模块的实例!这样是最理想的。

    也符合高内聚,低耦合原则。

    个人认为(3)是最理想的解决的方法。




  • 相关阅读:
    万能清除
    CSS追加笔记
    函数追加笔记
    jQuery实现放大镜效果
    jQuery获取元素的方法
    JavaScript
    jQuery三级联动
    DOM追加笔记
    数据结构与算法之美01
    RPC架构简介与原理
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6961977.html
Copyright © 2011-2022 走看看