结构体类型重声明导致的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对象的结构体属性整体赋值. 关于网上很多博客写着“结构体类型里面的某个属性如果想要修改是不允许单个修改的” 之解释: ...
随机推荐
- Spring可扩展Schema标签
基于Spring可扩展Schema提供自己定义配置支持 http://blog.csdn.net/cutesource/article/details/5864562 WARN : org.sprin ...
- Lesson 1 Basic Concepts: Part 1
www.how-to-build-websites.com/basic-concepts/part1.php An introduction to domain names, web servers, ...
- 37.微信跳一跳辅助开发(C语言+EasyX)
一.开发环境 开发环境 使用语言:C/C++ IDE:VS2010+ 其他三方库 EasyX(http://www.easyx.cn/downloads/) ADB(链接:https://pan.ba ...
- impala 概述
impala 概述 什么是Impala? Impala是用于处理存储在Hadoop集群中的大量数据的MPP(大规模并行处理)SQL查询引擎. 它是一个用C ++和Java编写的开源软件. 与其他Had ...
- OpenCV FileStorage类读写XML/YML文件
本文转自:http://www.cnblogs.com/summerRQ/articles/2524560.html 在OpenCV程序中,需要保存中间结果的时候常常会使用.xml / .yml文件, ...
- 进阶《Python高性能编程》中文PDF+英文PDF+源代码
入门使用高性能 Python,建议参考<Python高性能编程>,例子给的很多,讲到高性能就会提到性能监控,里面有cpu mem 方法的度量,网络讲了一点异步,net profiler 没 ...
- Windows 一键关闭UAC、防火墙、IE配置脚本
有时候,在环境需求下,需要关闭windows防火墙,UAC,以及IE选项配置. 对不懂电脑来说是比较麻烦的,老是得教他们,关键还记不住…… so,以下脚本就可以解决这个问题 注:脚本 需要右键 以管理 ...
- nginx下修改svn配置
最近公司的SVN服务器地址做了变更,而我用的操作系统是Ubuntu操作系统,我也不想把以前下载的代码重新进行修改,我想通过修改svn地址,应该可以,终于在网上通过查找资料,找到了解决的方法: ...
- Android NDK课程录制完毕上线
近期依据公司安排,录制了Android NDK开发的内容,总体课程能够在www.iotekclass.com上看到.兴许会慢慢的用blog把这些内容展示出来. 此课程大纲例如以下: 第一章 NDK简单 ...
- 【原生JS组件】javascript 运动框架
大家都知道JQuerry有animate方法来给DOM元素进行运动,CSS3中也有transition.transform来进行运动.而使用原生的Javascript来控制元素运动,须要写非常多运动的 ...