类似宏的函数和奇怪的行为 我开始阅读有效的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之前递增的次数 取决于它与什么进行比较类似宏的函数和奇怪的行为 我开始阅读有效的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,c++,macros,effective-c++,C++,Macros,Effective C++,这里,a在调用f之前递增的次数 取决于它与什么进行比较 事实上,如果我在f中使用一个简单的print语句,7会在第一次调用中被打印出来,但我一辈子都不知道为什么。我错过了什么明显的东西吗 编译器会将宏替换为您输入的内容,一字不差。所以你最终得到了 int a = 5, b = 0; f((++a) > (b) ? (++a) : (b)); f((++a) > (b+10) ? (++a) : (b+10)); 使用g++-E myprog.cpp(将g++替换为无论您的编译器是什
事实上,如果我在
f
中使用一个简单的print语句,7会在第一次调用中被打印出来,但我一辈子都不知道为什么。我错过了什么明显的东西吗 编译器会将宏替换为您输入的内容,一字不差。所以你最终得到了
int a = 5, b = 0;
f((++a) > (b) ? (++a) : (b));
f((++a) > (b+10) ? (++a) : (b+10));
使用
g++-E myprog.cpp
(将g++
替换为无论您的编译器是什么
,如果您没有使用g++
)-它可以在几乎所有的编译器上工作,它将在预处理后生成实际的内容
这是一个很好的例子,说明了为什么不应该使用宏来做函数类型的事情
如果使用内联函数,您将获得(可能)更多的期望:
inline void CallWithMax(int a, int b)
{
f((a) > (b) ? (a) : (b));
}
任何一个好的编译器都应该能够做到这一点,至少与宏一样高效,还有一个额外的优势,就是在调用代码中对a
和b
进行一次计算,并且不会发生任何“奇怪”的情况
如果您使用调试符号构建代码,还可以单步执行内联函数,因此如果您想查看函数中实际包含的
a
和b
值,可以这样做。宏,因为它们扩展到源代码中的原始位置,所以您无法真正看到内部的情况。@nhahtdh不仅仅是“思考”,宏还进行简单的文本替换。对于许多编译器(例如g++),你可以要求在预处理器通过后查看代码。这个故事的寓意是:在宏体中不要多次引用宏参数,否则会发生不好的事情。@NikBougalis-寓意是永远不要将宏应用于有副作用的参数。这也许是一种更好的表达方式。啊,是的!!谢谢你,我被卡住了