C语言中的宏陷阱
参考文章:《C与指针》
-
为宏定义中的变量以及宏定义体加上括号:
//正确方式 #define MUL(x,y) ((x)*(y)) //错误方式 #define MUL(x,y) (x*y)
否则按错误方式书写则可能出现如下错误:
MUL(a+b, c+d); //被编译为 a + b * c + d , 显然是错误的
-
定义多语句宏代码时,请使用 do{…}while() 语句:
//错误方式 #define ERROR_RET(x) {error_code=x;return false;} //正确方式 #define ERROR_RET(x) do{error_code=x;return false;}while(0);
是否感觉到很莫名其妙,为什么不能使用
{}
?看下面的例子:if(condition == true) ERROR_RET(x); else return true;
这段代码被编译成:
if(condition == true){ error_code=x; return false; }; else return true;
显然,第 4 行花括号后面的
;
是一个语法错误。关于do{}while()
的详细说明,参见do{}while()有什么用? 。 -
如果你不了解所使用的宏,则尽量不要在宏调用中发生动作:
什么是发生动作
?简单解释,就是操作变量或者调用函数,看下面的例子:#define MAX(a,b) ((a)>(b)?(a):(b)) //.... x = 5, y = 7; z = MAX(x++, y++); //较小的x自增了一次,结果较大的y却自增了两次
这种错误就比较隐蔽。对于宏定义中同一个变量出现多次的情况,更要预防这种错误 。函数调用也可能产生问题:
#define is_lower(ch) (((ch) > 'a' && (ch) < 'z') ? 1 : 0) //... is_lower(getchar());
宏展开后,getchar() 将会被调用两次,也就是说,缓冲区将消耗两个字符,这对后续的文本分析工作可能造成毁灭性影响。
其他注意事项待补充。
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
后端技术分享!
喜欢就支持一下吧