功能类宏和奇怪的行为

时间:2013-02-22 23:09:11

标签: c++ macros effective-c++

我已经开始阅读Effective C ++了,在第2项的某些时候,提到了以下内容:

// call f with the maximum of a and b
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))

...

int a = 5, b = 0;
CALL_WITH_MAX(++a, b); // a is incremented twice
CALL_WITH_MAX(++a, b+10); // a is incremented once
  

这里是a在调用f之前递增的次数   取决于与之相比的内容!

实际上,如果我在f中使用简单的打印语句,则在第一次调用时会打印7,但我不能为我的生活找出原因。我错过了一些明显的东西吗

2 个答案:

答案 0 :(得分:5)

编译器将文本替换为您传入的内容,逐字逐句。所以你最终得到了

int a = 5, b = 0;
f((++a) > (b) ? (++a) : (b));
f((++a) > (b+10) ? (++a) : (b+10));

答案 1 :(得分:1)

使用g++ -E myprog.cpp(如果您不使用g++,请将whatever-your-compiler-is替换为g++) - 它可以在ALMOST所有编译器上运行,它会在预处理后产生实际内容。

这是一个很好的例子,说明为什么你不应该使用宏来做函数类型的东西。

如果您使用内联函数,您可以获得更多(可能)期望的内容:

 inline void CallWithMax(int a, int b) 
 {
     f((a) > (b) ? (a) : (b));
 }

任何体面的编译器都应该能够像宏一样高效地执行此操作,并且在调用代码中对ab进行一次评估,并且没有任何“怪异”的额外优势发生。

如果使用调试符号构建代码,也可以逐步执行内联函数,因此,如果要查看函数内部实际存在的值ab,则可以执行此操作。宏,因为它们扩展到源代码中的原始位置,所以你无法真正看到内部发生的事情。