为什么要在Ideone上编译?

时间:2012-07-15 20:18:38

标签: c++

好的,所以我在Ideone上乱搞并意外地提交了这段代码,但令我惊讶的是它实际编译并运行输出值0 here

#include <iostream>

using namespace std;

const int five(  )
{
        const int i = 5;
}

int main() {
        cout << five(  ) << endl;
        return 0;
}

然后我在Visual Studio中尝试了这个,然后在Codepad上,但是两个都无法编译,因为five()没有返回值,正如人们所期望的那样。我的问题当然是,为什么在Ideone上编译正常,即使代码,我的理解是错误的,不应该编译。

4 个答案:

答案 0 :(得分:14)

简单明了(来自C ++ 11 6.6.3“返回语句”):

  

离开函数末尾相当于没有值的返回;这会导致值返回函数中的未定义行为。

因此,编译器几乎可以做任何想做的事情。显然,诊断是我更喜欢编译器的东西,但有时很难诊断(比如返回是在条件逻辑中,并且永远不会达到函数的'end')。 / p>

请注意,我使用GCC 4.6.1(使用Wall选项)收到以下警告:

test.cpp:8:1: warning: no return statement in function returning non-void [-Wreturn-type]

我不确定ideone传递给GCC的选项(我想-Wall会对ideone使用的4.3.4版本做同样的事情。)

一些相关信息:

在C中,声明返回值的函数在某些情况下实际上不会这样做是可以的;在C中,如果函数的返回值实际上是使用,则只会导致未定义的行为。预标准C并不总是支持void类型,因此未返回任何内容的函数通常被声明为显式或隐式返回int。从C99 6.9.1 / 12“函数定义”:如果到达函数终止的},并且调用者使用函数调用的值,则行为未定义。

另外,正如一些评论中所提到的那样,main()的末尾流动是由C ++和C99及更高版本专门处理的。

答案 1 :(得分:3)

不从非void函数返回值是错误的,但并非所有编译器都将其视为错误 - 例如,GCC在遇到此错误时仅发出警告。其他编译器可能是偏执的(并且它们是正确的)并且不允许您编译这样的代码。当然,可以使用不同的开关和选项修改编译器行为。

0的返回值只是一个随机值 - 它可能同样是255,-1或任何其他垃圾,因为这样做是未定义的行为(除了main,C99指定隐含的0返回值应该是假设)。

答案 2 :(得分:3)

似乎ideone不显示警告,只有在出现错误时才会显示编译器输出。在ideone正在使用的GCC版本(gcc 4.3)上,这不是错误,它只是一个警告。

答案 3 :(得分:2)

代码具有未定义的行为。即使您正在做的事情是错误的,编译器也不需要诊断它。另一点是,ideone使用的是现在相当古老的gcc版本。一个合理的当前版本的gcc(例如,4.7)将至少给你一个警告,声明你的函数被声明为返回一个值,但不是 - 但默认情况下不是。您必须使用类似-Wall的内容启用它才能收到警告(但一般来说,我总是至少使用-Wall和gcc)。