c++ - Gcc 4.8.3 没有发现丢失的 'return' 关键字

标签 c++ c++11 gcc gcc4.8

我们来看这样一段代码:

#include <iostream>

int foo(int i) {return i; }

int foobar(int z) {return foo(z);}

int main() {
std::cout << foobar(3) << std::endl;
}

它用 g++ -std=c++11 编译得很好...并给出输出 3。但是相同的输出由以下给出:

#include <iostream>

int foo(int i) {return i; }

int foobar(int z) { foo(z);}

int main() {
std::cout << foobar(3) << std::endl;
}

它编译没有问题,但显然 foobar 中缺少关键字 return。它是 gcc 4.8.3 中的错误还是我不知道某些 c++11 原则? (在 Fedora 20 上运行)

最佳答案

C++ 标准并未强制要求编译器在返回非void 的函数中坚持使用return 语句。相反,在没有 return 语句的情况下从此类函数的末尾流出是未定义的行为。标准中的相关声明在 6.6.3 [stmt.return] 第 2 段,最后一句(在 3.6.1 [basic.start.main] 第 5 段是声明 main() 流出这个函数):

Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

采用这种方法的主要原因是,如果函数真的返回,它可能非常重要甚至不可能。考虑这个函数声明和函数定义:

extern void will_always_throw();
int does_not_return_anything() {
    will_always_throw();
}

假设 will_always_throw() 确实如其名称所暗示的那样,没有错。事实上,如果编译器变得更聪明并设法验证 will_always_throw() 确实总是抛出(或者“noreturn”属性附加到 will_always_throw(),它可能会警告永远不会达到此定义中的最后一个语句:

int does_return_something_just_in_case() {
    will_always_throw();
    return 17;
}

处理这些情况的一般方法是让编译器支持适当的选项,以便在必要时启用/禁用警告。例如,在您的代码上,我有权访问的所有编译器( gccclangicc )都会创建一个警告,假设警告已启用(前两个使用 -Wall-w2 用于 Intel 的编译器)。

关于c++ - Gcc 4.8.3 没有发现丢失的 'return' 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27474578/

相关文章:

c++ - 与 GCC 配合使用的适用于 Windows 7 的免费 C/C++ IDE

c++ - 如何使用 C++ 获取路径的文件和目录列表?

c++ - 未知的段错误?

c++ - 缓存谷歌地图以供离线使用

c++ - 内联模板函数的编译错误

c++ - 使用一个数字数据成员为类定义所有比较运算符的便捷方法?

c++ - 用户类型的 hash<T> 仿函数属于哪个命名空间?

c# - C++ 右值引用和移动语义

android - arm-eabi-gcc 如何确保 crtbegin_dynamic.o 中的 ".text"部分在最终动态链接的可执行文件中排在第一位?

c++ - 内联值的优化