8

我遇到了一个奇怪的 VS2008 C++ 问题,看起来运算符优先级没有得到尊重。

我的问题是这个输出是什么:

int i = 0;  
std::cout << ((i != 0) ? "Not zero " : "zero ") << ++i << std::endl;  

通常++优先于<<,对吧?或者被<<认为是一个函数调用,赋予它比++?更高的优先级。100% 正确的标准答案是什么?

为了检查,我创建了一个新的空项目(VS2008 控制台应用程序),只在主目录中粘贴了这段代码,结果如下:

Debug|Win32: “zero 1”  
Release|Win32: “zero 1”  
Debug|x64: “zero 1”  
Release|x64: “Not zero 1”

顺便说一句,以下示例产生完全相同的结果:

i = 0;  
printf("%s %d\n", ((i != 0) ? "Not zero" : "zero"), ++i);  

并且在发布中更改优化类型也没有效果,但禁用优化会像其他配置一样输出“零 1”。

4

1 回答 1

16

这与运算符优先级无关。
您正在使用 << 这是函数调用的语法糖:

std::cout << ((i != 0) ? "Not zero " : "zero ") << ++i << std::endl; 

// Equivalent too:

operator<<(operator<<(operator<<(std::cout, ((i != 0) ? "Not zero " : "zero ")), ++i), std::endl);

这里唯一的规则是在调用函数之前必须对参数进行完全评估。对参数的评估顺序没有限制,或者即使它们的评估与调用交错(甚至部分评估)也没有限制。

解读一:

1) ((i != 0) ? "Not zero " : "zero "))
2) ++i
3) operator<<(std::cout, (1));
4) operator<<((3), (2));
5) operator<<((4), std::endl);

解读二:

1) ++i
2) ((i != 0) ? "Not zero " : "zero "))
3) operator<<(std::cout, (2));
4) operator<<((3), (1));
5) operator<<((4), std::endl);

解读3:

1) ((i != 0) ? "Not zero " : "zero "))
2) operator<<(std::cout, (1));
3) ++i
4) operator<<((2), (3));
5) operator<<((4), std::endl);

将解释 1 视为参考:
必须应用的规则:

 A) (1) happens before (3)
 B) (2) happens before (4)
 C) (3) happens before (4)
 D) (4) happens before (5)
于 2010-08-11T22:29:11.507 回答