2008-11-16 43 views
14

昨天,我发现自己编写的代码是这样的:如果您不在C++中返回值,会发生什么情况?

SomeStruct getSomeStruct() 
{ 
    SomeStruct input; 

    cin >> input.x; 
    cin >> input.y; 
} 

当然不忘回报其实我刚刚创建的结构体。奇怪的是,这个函数返回的结构中的值被初始化为0(当使用g ++编译时)。这只是一个巧合,还是另一个SomeStruct被隐式地创建并初始化了?

回答

7

做了另一个SomeStruct获得创建和隐式初始化的地方?

想想如何返回结构。如果xy都是32位,那么32位体系结构中的寄存器就太大了,64位体系结构中的64位值也是如此(@Denton Gentry的答案提到了简单的值是多少返回),所以它必须分配到某个地方。使用这个堆是浪费的,所以它必须在堆栈上分配。但它不能在你的函数的栈帧上,因为函数返回后它不再有效。

编译器,而不是具有来电告诉调用的函数放在哪里的结果(这可能是某处调用者的堆栈上),通过将调用的函数隐藏指针分配给它的空间。因此,它被设置为零的位置在调用者上,而不是在您的getSomeStruct函数上。

也有像“命名的价值回归优化”里多余的副本可以被省略优化。因此,如果您使用了缺少的return,结果将直接在调用者分配的空间上创建,而不是创建临时文件并将其复制。

要了解更多有关正在发生的事情,您必须查看调用者函数。它是初始化(为零)一个“空”SomeStruct,你稍后分配你的getSomeStruct函数的返回值?还是在做别的事情?

2

对我来说,编译器不允许它:http://codepad.org/KkzVCesh

+0

看起来它不允许它,因为你的编译器设置了警告被视为错误。你认为这可能是我的警告级别设置得太低的情况吗? – 2008-11-16 04:41:58

20

脱落的一个声明返回一个值(无明确返回值)函数的结束导致不确定的后果。对于gcc,您应该从开启最有用的警告的-Wall命令行开关开始。控制所需警告的具体gcc警告是-Wreturn-type(包含在-Wall中,我只是为了完整性而提及)。

打开警告后,您还应该使用-Werror将警告视为错误,并使构建在检测到错误的位置停止。

+1

我一直很惊讶,这只是一个警告,而不是一个错误。它比它帮助更多地受到伤害。 – 2008-11-16 05:24:54

+0

在C中不返回任何东西是合法的,它仍然没有定义,但至少它是合法的。 – Jonathan 2008-11-16 06:55:18

8

对于大多数现代CPU架构的调用约定指定一个特定的寄存器来传递一个函数的返回值返回给调用者。调用者进行函数调用,然后使用指定的寄存器作为返回值。如果你没有明确地返回一个值,调用者将会使用该寄存器中的任何垃圾。

编译器还将使用该函数内可用于内部计算的所有寄存器。指定用于保存返回值的寄存器也将用于该函数内的混杂计算。因此,当你忘记指定返回值时,找到正确的值奇迹般地返回给调用者并不罕见:编译器使用该寄存器来存储对象。

不幸的是,即使在功能的琐碎的变化会导致寄存器分配发生变化,因此,返回值将成为真正的垃圾。

1

您没有收到任何警告,因为您没有打开-Wall -Werror。 (正如在其他答案中所述)

但是我认为你可能得到了一个零填充的结果作为结果,因为堆栈对象是在调用函数中构造的默认值,可能带有显式的零参数,或者由于零上的零叠加么?

3

我觉得这很有趣。随着使用默认选项,下面的编译器在编译的GetSomeStruct()功能时,以下行为:

  • 微软VC,所有版本(因为VC6反正):

    error C4716: 'getSomeStruct' : must return a value

  • 数字火星:

    Warning 18: implied return of getSomeStruct at closing '}' does not return value

  • 科莫:

    warning: missing return statement at end of non-void function "getSomeStruct"

  • GCC:

    没有错误或鉴于以下几个从标准(6.6句子的警告

。 3第2段):

没有 表达式的return语句可用于仅在 函数不返回一个值, 即,与返回 型空隙的功能,构造(12.1),或一个 析构函数( 12.4)。 ...流失 函数的结尾等于 返回无值;这导致 处于未定义行为的 值返回函数。

我会说在这种情况下编译器不会给出错误的原因很少。为什么这么多编译器只给出警告或根本没有诊断?

相关问题