结构体类型重声明导致的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\n", new.name);
} int main(int argc, char *argv[])
{
printf("call output:\n");
output();
printf("call test_output:\n");
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\n", new.name);
else
printf("name is null\n");
}
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)是最理想的解决的方法。
结构体类型重声明导致的bug一个的更多相关文章
- 让结构体类型frame的某个属性可以直接修改
本篇是是本人在博客园写的第一篇博客,前几天因为种种原因最终决定离开混了几年的csdn.希望在博客园有个新的开始 Foundation框架里面的frame是大家最熟悉不过的一个属性了,但是修改起来比较麻 ...
- typedef和自定义结构体类型
在自定义结构体类型时会用到typedef关键字.大家都知道typedef是取别名的意思,在C语言中跟它容易混淆的有const,#define等,其区别不在本篇文章讨论之列. /*定义单链表结点类型*/ ...
- Go语言规格说明书 之 结构体类型(Struct types)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- 张超超OC基础回顾03_结构体类型作为成员变量的特殊用法
直接上例子: 要求: 合理的设计一个”学生“类 学生有* 姓名* 生日两个属性和说出自己姓名生日方法 要求利用设计的学生类创建学生对象,并说出自己的姓名和年龄 描述学生类 事物名称: 学生(Stud ...
- 自定义数据类型 C++ 结构体类型 共同体类型 枚举类型 类类型{}
一.结构体类型 结构体类型,共用体类型,枚举类型,类类型等统称为自定义类型(user-defined-type,UDT). 结构体相当于其他高级语言中的记录(record);例如: struct St ...
- 你好,C++(14)如何描述“一个名叫陈良乔,年龄33岁,身高173厘米,体重61.5千克的男人”——3.8 用结构体类型描述复杂的事物
3.8 用结构体类型描述复杂的事物 利用C++本身所提供的基本数据类型所定义的变量,只能表达一些简单的事物.比如我们可以用int类型定义nAge变量表示人的年龄,用string类型定义strName ...
- C语言中的系统时间结构体类型
在C语言涉及中经常需要定时触发事件,涉及到获取系统时间,其结构体类型有多种.Unix/Linux系统下有以下几种时间结构: 1.time_t 类型:长整型,一般用来表示从1970-01-01 00:0 ...
- go语言进阶之为结构体类型添加方法
1.为结构体类型添加方法 示例: package main import "fmt" type Person struct { name string //名字 sex byte ...
- OC对象里面包含的结构体类型的属性,不能对该结构体属性的成员单个进行修改
OC对象里面包含的结构体类型的属性,不能对该结构体属性的成员单个进行修改,需要对OC对象的结构体属性整体赋值. 关于网上很多博客写着“结构体类型里面的某个属性如果想要修改是不允许单个修改的” 之解释: ...
随机推荐
- 【J-meter】调试JDBC请求
参考资料: http://www.codesec.net/view/165234.html
- numpy基础篇-简单入门教程3
np import numpy as np np.__version__ print(np.__version__) # 1.15.2 numpy.arange(start, stop, step, ...
- 网络编程select函数
select函数的作用: 在编程的过程中,经常会遇到许多阻塞的函数,好像read和网络编程时使用的recv, recvfrom函数都是阻塞的函数,当函数不能成功执行的时候,程序就会一直阻塞在这里,无法 ...
- 【BZOJ 1045】 [HAOI2008] 糖果传递
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 思路来自hzwer.. 设xi表示第i个人往左传递了xi个糖果. (如果小于0表示旁边的人给他了糖果. 则ans=∑|xi| 最后所 ...
- 移动App架构设计
移动App架构设计 本文主要总结了几种经常使用的架构模式, 基本是层层递进的转载请注名出处 http://blog.csdn.net/uxyheaven, 良好的排版在https://github.c ...
- 22. Angular 中用 a 标签 href 路由时在浏览器中显示异常 "%2F" 路由失败问题
转自:https://blog.csdn.net/duansale/article/details/77455355 <a href="#/index">index&l ...
- 公司采购 流程flowable例子
Name: Flowable BPMN 2.0 designer Location: http://flowable.org/designer/update/ 业务描述:1. 公司采购,因为办公用品价 ...
- Gym - 100203H Highways 最小生成树
题意:平面上n个点修路,已经修好了m条,再修若干条使得点之间连通,求最小代价的方案. 思路:基本上是裸的最小生成树了,我这里存边直接存在multyset了,取的时候也比较方便,我本来就是这么考虑的,队 ...
- 手动新建hive编程环境(以hive-1.0.0和hive-1.2.1为例)
如下,是用maven构建项目,本篇博文重点不是这个.初学者(小白)变成小鸟后,建议开始用maven啦! Eclipse下Maven新建项目.自动打依赖jar包(包含普通项目和Web项目) HBase ...
- SQL server无法启动服务,提示“错误1069: 由于登录失败而无法启动服务”
原因:大部分情况是你修改了服务器系统的登录密码,而导致SQL服务无法启动. 解决方法:将sql server(mssql server)服务的登录密码改为系统登录密码或本地登录,如下操作步骤: 在wi ...