C++ 预处理器中的前缀增量

Posted

技术标签:

【中文标题】C++ 预处理器中的前缀增量【英文标题】:Prefix increment in C++ preprocessor 【发布时间】:2011-05-30 19:33:48 【问题描述】:

有人能解释一下为什么 b = 150 吗?

#define CUBE(X) ((X) * (X) * (X))

using namespace std;

int main( void )

    int a = 3,b = 0;  

    cout << "before "<< endl;
    cout << "a = " << a;
    cout << endl;
    cout << "b = " << b;
    cout << endl;
    cout << "after"<< endl;
    b = CUBE( ++a );
    cout << "a = " << a;
    cout << endl;
    cout << "b = " << b;
    getchar();
    return 0;

【问题讨论】:

C, C++ preprocessor macro 的可能重复项 @BoPersson:相关,但不是重复的......尤其是因为它没有通过在序列点之间多次递增来实现 UB。 【参考方案1】:

因为您使用的是宏。宏不是函数。

行:

b = CUBE( ++a );

被重写为:

b = ((++a) * (++a) * (++a))

在您的代码编译之前。

The code then invokes Undefined Behaviour 因为您在序列点之间将a 增加了几次。

如果你使用一个函数会更好。

【讨论】:

是的,我知道内联函数更好,但我只需要这个问题的答案;)如果我得到 b = CUBE(a++),我会理解情况; @wolf3d:++a 的情况与a++ 的情况相同。在序列点之间更改和读取a 的任何操作集合都是未定义的。 @wol3d:正如 Tomalak Geret'kal 所说,a++ 行为未定义。也许你了解编译器生成了什么代码,但这并不意味着每个编译器都会这样做,或者同一编译器的其他版本也会这样做。 感谢您的重播,通读一遍,我在纸上找到了 b 的价值:D @wolf3d:你怎么能在一张纸上算出来?这里没有错误的答案。我的编译器给出 216。【参考方案2】:

(++a) * (++a) * (++a) 是undefined behaviour。

【讨论】:

【参考方案3】:

未定义的行为 - 您在序列点之间多次修改 a。这就是为什么 inline 函数是非常优越的选择。

【讨论】:

以上是关于C++ 预处理器中的前缀增量的主要内容,如果未能解决你的问题,请参考以下文章

预处理器中的 C# 宏定义

后缀(前缀)增量、左值和右值(在 C 和 C++ 中)

gcc 预处理器中的去字符串化

php 布局构建器中的facetwp数组处理

处理 BeautifulSoup CSS 选择器中的冒号

argparse 未正确处理子解析器中的缩写