在C ++中省略return语句

时间:2010-08-04 02:30:22

标签: c++ g++ strawberry-perl

我刚从草莓Perl的g ++版本获得了一些奇怪的行为。它允许我省略一个返回声明。

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

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

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

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

3 个答案:

答案 0 :(得分:16)

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

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

  

可以使用带表达式的return语句     仅在返回值的函数中;表达式的值是     返回给函数的调用者。如果需要,表达式     隐式转换为函数的返回类型     出现。退货声明可能涉及构造和复制     临时对象( class.temporary )。 流动结束了     函数相当于没有值的返回;这导致了     值返回函数中的未定义行为

例如

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选项进行编译。

答案 1 :(得分:12)

C和C ++不要求您拥有return语句。 可能没有必要有一个,因为函数进入无限循环,或者因为它抛出异常。

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

[第6.6.3 / 2条]

  

带表达式的return语句只能用于返回值的函数;表达式的值返回给函数的调用者。如果需要,表达式将隐式转换为其出现的函数的返回类型。 return语句可以包含临时对象(class.temporary)的构造和复制。流出函数末尾相当于没有值的返回;这会导致值返回函数中的未定义行为。

这意味着没有一个return语句就可以了。但到达函数的末尾而不返回未定义的行为

编译器无法始终检测到这些情况,因此不需要编译错误(它必须解决暂停问题以确定执行实际是否到达结束时功能)。它只是 undefined 如果发生这种情况会发生什么。它似乎可行(因为调用函数只会查看返回值所在位置的垃圾值),它可能会崩溃,或者让恶魔飞出你的鼻子。

答案 2 :(得分:2)

即使aC ++编译器无法总是检测到函数何时无法执行return语句,通常也可以。

从好的方面来说,至少使用g ++可以使用命令行编译器选项“-Wreturn-type”轻松检测到它。你只需要记住启用它。 (如果使用“-Wall”,它也会启用。)