【问题标题】:Omitting return statement in C++在 C++ 中省略 return 语句
【发布时间】:2010-08-04 02:30:22
【问题描述】:

我刚刚在使用 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"
    }
}

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

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

【问题讨论】:

  • 你应该使用-Wall进行编译。缺少的返回语句被-Wreturn-type 捕获。
  • 我倾向于将有关缺少返回的警告变成错误:-Werror=return-type。为我节省了很多时间。

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


【解决方案1】:

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

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

可以使用带有表达式的返回语句 仅在返回值的函数中;表达式的值为 返回给函数的调用者。如果需要,表达式 隐式转换为它所在函数的返回类型 出现。退货声明可能涉及构建和复制 一个临时对象(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 选项进行编译。

【讨论】:

  • 省略 return 语句是可以的。在没有遇到 return 语句的情况下执行到函数末尾会导致未定义的行为。您可以在到达函数末尾之前返回,或者通过抛出异常离开,或者根本不离开,一切都会很好地定义。
  • 为什么使用p 很危险?
  • @ajay:那是因为 is 不包含任何指定的值。
  • 实际上,使用 -Wall 甚至 -Werror 编译不会显示此错误的任何内容。至少 Ubuntu 上的 g++ 4.8.1 没有。-Wreturn-type 确实有帮助。
  • @yuvi - 按照标​​准,您可以安全地省略 main() 中的 return 语句,返回值默认为 0。
【解决方案2】:

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

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

[第 6.6.3/2 节]

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

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

编译器不能总是检测到这些情况,所以它不需要是编译错误(它必须解决停止问题以确定执行是否实际上到达了功能)。如果发生这种情况,这只是undefined。它可能看起来有效(因为调用函数只会查看返回值应该在的位置中的任何垃圾值),它可能会崩溃,或者让恶魔飞出你的鼻子。

【讨论】:

  • 感谢您解释为什么在非 void 函数中没有显式返回语句不是编译错误 :)
【解决方案3】:

尽管 C++ 编译器不能总是检测到函数何时不能执行 return 语句,但它通常可以。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多