在编写 c/c++ 代码时,我们通常使用 #define
定义一些宏,然后编译器在 预处理 阶段会把用到宏的地方替换为宏的内容,由于宏的替换完全是一种文本替换,所以在一些情况下如果使用不当,容易产生副作用。
运算符优先级问题
考虑如下宏定义:
|
|
使用1:
|
|
预处理后:
|
|
预处理之后的代码,符合我们的预期。
使用2:
|
|
预处理后:
|
|
这时预处理后的代码,就产生了副作用,由于 *
运算符的优先级高于 >
,所以编译之后,优先执行 3 * 1
,执行结果就成了 1,而不是期望的 6。
解决方法: 使用 ()
包裹宏的内容,以避免优先级问题。
|
|
宏参数传递表达式问题
考虑如下宏定义:
|
|
这个宏的定义,就采用了 ()
包裹,虽然避免了运算符优先级问题,但是还是存在副作用。考虑如下使用方式:
|
|
预处理之后:
|
|
由于预处理是直接的文本替换,就会造成表达式会被执行两次,也产生了副作用。于是一般会在宏里额外定义局部变量来避免副作用:
|
|
|
|
预处理之后:
|
|
保证了表达式只被执行一次。