在C ++中省略return语句

我只是从我用Strawberry Perl获得的Windows版本g ++中发现了一些奇怪的行为。 它使我可以省略一个返回声明。

我有一个成员函数返回一个由两个指针组成的结构,叫做boundTag

 struct boundTag Box::getBound(int side) { struct boundTag retBoundTag; retBoundTag.box = this; switch (side) { // set retBoundTag.bound based on value of "side" } } 

这个函数给了我一些不好的输出,我发现它没有return语句。 我本来打算返回retBoundTag但忘了实际写回报语句。 一旦我添加return retBoundTag; 一切(曾经)都很好。

但是我testing了这个函数,并boundTag得到了正确的boundTag输出。 即使现在,当我删除返回语句,g ++编译它没有警告。 WTF? 它猜测返回retBoundTag

non-void函数中省略return语句[ main()除外],并在代码中使用返回的值调用Undefined Behavior 。

ISO C ++ – 98 [第6.6.3 / 2节]

带expression式的return语句只能用于返回值的函数; expression式的值被返回给函数的调用者。 如果需要,expression式将隐式转换为它所在函数的返回types。 返回声明可能涉及临时对象( class.temporary )的构build和复制。 从函数的结尾stream出相当于没有值的返回; 这会导致值返回函数中的未定义行为

例如

 int func() { int a=10; //do something with 'a' //oops no return statement } int main() { int p=func(); //using p is dangerous now //return statement is optional here } 

一般来说g ++会给出一个warning: control reaches end of non-void function 。 尝试使用-Wall选项编译。

C和C ++不要求你有一个return语句。 可能没有必要有一个,因为该函数进入一个无限循环,或因为它引发一个exception。

Prasoon已经引用了标准的相关部分:

[第6.6.3 / 2节]

带expression式的return语句只能用于返回值的函数; expression式的值被返回给函数的调用者。 如果需要,expression式将隐式转换为它所在函数的返回types。 返回声明可能涉及临时对象(class.temporary)的构build和复制。 从函数的结尾stream出相当于没有值的返回; 这会导致值返回函数中的未定义行为。

这意味着没有返回声明是可以的。 但是,在不返回情况下到达函数的末尾未定义的行为

编译器不能总是检测到这些情况,所以不需要编译错误(它必须解决暂停问题,以确定执行是否真的到达函数的结尾)。 这是不明确的 ,如果发生这种情况应该发生什么。 它可能似乎工作(因为调用函数只会查看返回值所在位置的垃圾值),它可能会崩溃,或使恶魔飞出你的鼻子。

即使一个C ++编译器不能总是检测函数何时不能执行返回语句,它通常可以。

从好的一面来看,至less使用g ++可以很容易地通过命令行编译选项“-Wreturn-type”来检测。 你只需要记住启用它。 (如果使用“-Wall”,它也会被启用。)