在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”,它也会被启用。)