kot*_*otu 1 c++ gcc c++11 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;
}
Run Code Online (Sandbox Code Playgroud)
它用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;
}
Run Code Online (Sandbox Code Playgroud)
它编译没有问题,但显然foobar错过了关键字返回.这是gcc 4.8.3中的错误还是我不知道某些c ++ 11原则?(在Fedora 20上运行)
C++标准没有要求编译器坚持return函数返回非语句void.相反,在没有return-statement的情况下流出这样一个函数的结尾是未定义的行为.标准中的相关陈述在6.6.3 [stmt.return]第2段,最后一句(以及在3.6.1 [basic.start.main]第5段中是使该main()流程可以流出的声明):
流出函数末尾相当于没有值的返回; 这会导致值返回函数中的未定义行为.
这种方法的主要原因是,如果函数实际上真正返回,它可能是非平凡的,甚至是不可能的.考虑这个函数声明和函数定义:
extern void will_always_throw();
int does_not_return_anything() {
will_always_throw();
}
Run Code Online (Sandbox Code Playgroud)
假设will_always_throw()确实顾名思义,没有错.事实上,如果编译器变得更聪明并且设法验证will_always_throw()确实总是抛出(或附加了"noreturn"属性will_always_throw(),它可能会警告到此定义中的最后一个语句永远不会到达:
int does_return_something_just_in_case() {
will_always_throw();
return 17;
}
Run Code Online (Sandbox Code Playgroud)
处理这些情况的一般方法是编译器支持在必要时启用/禁用警告的适当选项.例如,在您的代码中,我有权访问(gcc,clang和icc)的所有编译器都会发出警告,假设警告已启用(使用-Wall前两个和-w2英特尔编译器).