作者:gfree.wind@gmail.com
博客:linuxfocus.blog.chinaunix.net
在产品的开发过程中,无论是代码的重构,还是添加新的功能时,都不可避免的有对现有结构体的修改,比如结构体成员变量名字的修改,类型的变动,等等。如果只是修改名字,使用工具,就可以把所有的改动完成了。但是如果是成员变量的类型发生了变化,就不是不能简单的依靠工具完成了。而且作为人工的工作,每个开发人员的进展速度不一样,如果不能同时完成修改,那么每天的工程的自动build就无法完成。下面举个例子,比如有这样的一个structure
- typedef structure {
char name[MAX_NAME_LEN]; - unsigned short height;
- // ... ...
-
} STUDENT_INFO_S;
用于表示学生的个人信息,那么代码中肯定会有很多地方引用name
- STUDENT_INFO_S student;
-
char name[MAX_NAME_LEN]
-
// ......
-
strncpy(name, student.name, sizeof(name)-1);
但是现在有了新的需求。不能直接把学生的姓名直接存入一个字符数组了,而是需要一个结构体
- typedef {
- char name[MAX_NAME_LEN];
-
char first_name[MAX_NAME_LEN];
-
char last_name[MAX_NAME_LEN];
-
} NAME_INFO_S;
如果我们直接使用这个结构体作为新的name类型,来取代原有的字符数组,
- typedef structure {
-
NAME_INFO_S name;
-
unsigned short height;
-
// ... ...
-
} STUDENT_INFO_S;
那么毫无疑问,在不修改代码的情况下,会有很多地方无法通过编译。如果这样的地方很多,我们为了不妨碍每天的自动build,可能会快速的修改以前的代码——这无疑有着一定的引入bug的风险。
那么遇到这种情况时,我们可以使用union来避免这个问题,既在新的代码中可以使用新的结构体,同时又不会影响build和以前代码的逻辑。
- typedef structure {
- union {
- char name[MAX_NAME_LEN];
- NAME_INFO_S name_info;
- };
-
unsigned short height;
-
// ... ...
-
} STUDENT_INFO_S;
这里应用了gcc的一个扩展特性,当不对union或者struct命名时,外层可以直接引用union或者struct中的成员变量。比如STUDENT_INFO_S student, 我们可以直接使用student.name_info或者student.name。
通过这样一个小技巧,我们可以在新的代码中,使用新的成员变量,同时不会影响到以前代码的编译。如果新的类型中,包含了以前老的类型且位于第一个时,甚至不会影响到以前老代码的逻辑。这样可以允许开发人员仔细的,慢慢修改以前的代码。
阅读(934) | 评论(0) | 转发(0) |