g ++和运算符<<在评估期间改变价值时会产生无意的结果

时间:2013-03-05 18:45:29

标签: c++ g++ clang++

这是一些简单的代码。

#include <iostream>
using namespace std;

bool func(char* m)
{
    *m = '4';
    return true;
}

using namespace std;
int main()
{
    char c1 = '3';
    cout  << "a" << c1 << func(&c1) << c1 << "b" << endl;

    return 0;
}

用g ++ -O0(4.7.2)编译时,输出为a413b,对于-O2,输出为a414b。 对于clang ++ 3.2,输出为a314b。

在这部分代码中,我是否为c ++做了任何未定义的事情?

2 个答案:

答案 0 :(得分:5)

是的,func(&c1)和两个c1的评估顺序未指定。

这意味着可以按任何顺序评估这三个表达式,从而产生以下任何输出:

a313b
a314b
a413b
a414b

请参阅function parameter evaluation order

答案 1 :(得分:5)

我们会稍微缩短你的例子以包围它。我们来看代码:

char func(char* m) { *m = '4'; return *m; }

int main() {
    char c = '1';
    cout << c << func(&c);

}

cout行变换如下:

operator<<(operator<<(cout, c), func(&c))

因为函数参数可以按任何顺序计算,所以编译器可以先选择评估内部operator<<(cout, c),或先评估func(&c)。根据首先评估的是哪一个,您将获得:

`14`

`44`