我正在写一些C++代码,用于娱乐和练习,以了解有关语言特性的更多信息。我想更多地了解静态变量及其在递归函数中的行为。在g++编译器中尝试这段代码,我得到了预期的结果:
#include <iostream>
using namespace std;
int f(const int& value)
{
static int result = 0;
return result += value;
}
int main()
{
cout << f(10) << ", " << f(f(10)) << ", " << f(f(f(10)));
return 0;
}但是我的朋友在MicrosoftVisualLinux6上测试了同样的代码,输出是50, 80, 90,我用其他的C++编译器(g++,Borland,C++::blocks和MingW在Linux,Win和Mac下测试的)输出是110, 100, 40。我不明白输出怎么会是50, 80, 90 ...
为什么MSVC的输出是不同的?
发布于 2011-03-02 01:28:40
以下三个子表达式的求值顺序未指定:
f(10)
f(f(10))
f(f(f(10)))编译器可以按任何顺序对这些子表达式求值。您不应该在程序中依赖于特定的求值顺序,特别是当您打算使用多个编译器进行编译时。
这是因为该表达式中的任何位置都没有序列点。唯一的要求是在需要结果之前(即打印结果之前)对每个子表达式进行求值。
在您的示例中,实际上有几个子表达式,我在这里将其标记为a到k:
// a b c d e f g h i j k
cout << f(10) << ", " << f(f(10)) << ", " << f(f(f(10)));对operator<< (a、c、d、g和h)的调用都必须按顺序进行计算,因为每个调用都依赖于前一次调用的结果。同样,在评估a之前必须先评估b,在评估j、i或h之前必须评估k。
但是,这些子表达式之间没有依赖关系:b的结果不依赖于k的结果,因此编译器可以自由生成代码,该代码先计算k,然后计算b,或者先计算b,然后计算k。
有关序列点和相关的未指定和未定义行为的更多信息,请考虑阅读堆栈溢出C++常见问题解答文章"Undefined Behavior and Sequence Points" (您的程序没有任何未定义的行为,但该文章的大部分内容仍然适用)。
https://stackoverflow.com/questions/5158014
复制相似问题