首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么不同的C++编译器会对这段代码产生不同的结果?

为什么不同的C++编译器会对这段代码产生不同的结果?
EN

Stack Overflow用户
提问于 2011-03-02 01:24:38
回答 3查看 3.9K关注 0票数 1

我正在写一些C++代码,用于娱乐和练习,以了解有关语言特性的更多信息。我想更多地了解静态变量及其在递归函数中的行为。在g++编译器中尝试这段代码,我得到了预期的结果:

代码语言:javascript
运行
复制
#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的输出是不同的?

EN

Stack Overflow用户

回答已采纳

发布于 2011-03-02 01:28:40

以下三个子表达式的求值顺序未指定:

代码语言:javascript
运行
复制
f(10)
f(f(10))
f(f(f(10)))

编译器可以按任何顺序对这些子表达式求值。您不应该在程序中依赖于特定的求值顺序,特别是当您打算使用多个编译器进行编译时。

这是因为该表达式中的任何位置都没有序列点。唯一的要求是在需要结果之前(即打印结果之前)对每个子表达式进行求值。

在您的示例中,实际上有几个子表达式,我在这里将其标记为a到k:

代码语言:javascript
运行
复制
//   a  b     c       d  e f      g       h  i j k
cout << f(10) << ", " << f(f(10)) << ", " << f(f(f(10)));

operator<< (acdgh)的调用都必须按顺序进行计算,因为每个调用都依赖于前一次调用的结果。同样,在评估a之前必须先评估b,在评估jih之前必须评估k

但是,这些子表达式之间没有依赖关系:b的结果不依赖于k的结果,因此编译器可以自由生成代码,该代码先计算k,然后计算b,或者先计算b,然后计算k

有关序列点和相关的未指定和未定义行为的更多信息,请考虑阅读堆栈溢出C++常见问题解答文章"Undefined Behavior and Sequence Points" (您的程序没有任何未定义的行为,但该文章的大部分内容仍然适用)。

票数 14
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5158014

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档