g ++和operator <<在评估期间更改值时会产生无意的结果

css*_*yer 3 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;
}
Run Code Online (Sandbox Code Playgroud)

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

我在这部分代码中为c ++做了什么未定义的事情吗?

NPE*_*NPE 5

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

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

a313b
a314b
a413b
a414b
Run Code Online (Sandbox Code Playgroud)

请参阅功能参数评估顺序


Col*_*lin 5

我们会缩短你的例子以包围我们的头脑.我们来看看代码:

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

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

}
Run Code Online (Sandbox Code Playgroud)

cout行变换如下:

operator<<(operator<<(cout, c), func(&c))
Run Code Online (Sandbox Code Playgroud)

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

`14`
Run Code Online (Sandbox Code Playgroud)

要么

`44`
Run Code Online (Sandbox Code Playgroud)