一个变量引发的血案

左天提交了代码, 大致测一下, 看起来来都OK啦. 今天准备放出去呢, 结果一来就各种不正常, 程序直接乱崩, Firmware各种跑死, 等等各种现象层出不穷.
所以今天可以是称为史上最悲剧的一天啦, 还是说原因吧, 希望以后不要再犯.

————————————————————————–

在之前的软件中使用了类似这样一个结构体:

struct a {
int a;
int b;
int c;
int d;
};

这个结构体类似一个全局结构体, 在a.exe与b.dll中同时使用. 但是a.exe与b.dll是由不同的人维护的. 在近期发现要实现某种功能必须要向struct a中加入字段a1, 于是我就将上述代码修改如下:

struct a {
int a;
int a1;
int b;
int c;
int d;
};

然后我编译了a.exe然后将之前的b.dll拷入安装目录下, 测试软件功能时发现都OK, 因为这时候Firmware压根儿就没跑, 今天在具体测试时, 是Firmware各种死啊(b.dll中从struct a中的变量导出另一种结构体, 给Firmware使用). 下班前才发现, 因为我把变量int a1放在了 int a后面, 而b.dll还是以原来的结构体来取数据, 这样他取出来的数据永远偏了4个byte.而Firmware获得信息不正确, 所以才各种死.
原因很简单, 但是死的很难看.

————————————————————————–

所以如果新增加功能时代码中有类似成员变量需要添加, 那么尽可能的将新加的成员变量放在结构体的最后, 保正向低版本代码兼容. 正确的修改如下:

struct a {
int a;
int b;
int c;
int d;
int a1;
};

这样就能兼容旧的代码, 因为旧的代码中有可能某些DLL没有用到这些字段, 那么只要不影响他们的正确取值程序就能证明, 道理很简单, 坑也很明显, 谁踩谁知道…



发表评论