我们来看这样一段代码:
#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;
}
处理这些情况的一般方法是让编译器支持适当的选项,以便在必要时启用/禁用警告。例如,在您的代码上,我有权访问的所有编译器( gcc
、 clang 和 icc
)都会创建一个警告,假设警告已启用(前两个使用 -Wall
和 -w2
用于 Intel 的编译器)。
关于c++ - Gcc 4.8.3 没有发现丢失的 'return' 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27474578/