Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类似宏的函数和奇怪的行为 我开始阅读有效的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++ - Fatal编程技术网

类似宏的函数和奇怪的行为 我开始阅读有效的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++,在项目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++替换为无论您的编译器是什

这里,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++
替换为
无论您的编译器是什么
,如果您没有使用
g++
)-它可以在几乎所有的编译器上工作,它将在预处理后生成实际的内容

这是一个很好的例子,说明了为什么不应该使用宏来做函数类型的事情

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

 inline void CallWithMax(int a, int b) 
 {
     f((a) > (b) ? (a) : (b));
 }
任何一个好的编译器都应该能够做到这一点,至少与宏一样高效,还有一个额外的优势,就是在调用代码中对
a
b
进行一次计算,并且不会发生任何“奇怪”的情况


如果您使用调试符号构建代码,还可以单步执行内联函数,因此如果您想查看函数中实际包含的
a
b
值,可以这样做。宏,因为它们扩展到源代码中的原始位置,所以您无法真正看到内部的情况。

@nhahtdh不仅仅是“思考”,宏还进行简单的文本替换。对于许多编译器(例如g++),你可以要求在预处理器通过后查看代码。这个故事的寓意是:在宏体中不要多次引用宏参数,否则会发生不好的事情。@NikBougalis-寓意是永远不要将宏应用于有副作用的参数。这也许是一种更好的表达方式。啊,是的!!谢谢你,我被卡住了