Gcc 4.8.3 没有发现缺少的"返回"关键字
Gcc 4.8.3 does not spot missing 'return' keyword
让我们看一下这样的代码段:
#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 中缺少关键字返回。这是 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()
可以流出此功能(:
从函数末尾流出等效于没有值的返回;这会导致值返回函数中出现未定义的行为。
这种方法的主要原因是,如果函数实际上真的返回,它可能不是平凡的,甚至是不可能的。请考虑以下函数声明和函数定义:
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
(。
代码编译良好,因为它的格式正确,因此您可以运行它。但由于这是未定义的行为,因此您不能依赖程序的任何行为,任何事情都是合法的。若要防止此类事故,请启用编译器警告。如果使用 -Wall
编译代码,您将看到
main.cpp:10:28: warning: no return statement in function returning non-void [-Wreturn-type]
int foobar(int z) { foo(z);}
在这里,您可以获得有关这些警告的更多信息。使用它们并确保您的代码编译无警告。它可以在编译时捕获代码中的许多错误。
- 是否可以将“自动”关键字用作函数指针声明中使用初始化的返回类型
- 是尾部递归所需的返回关键字
- 使用关键字从文本文件返回数字
- 如果我返回const定义的对象,为什么const关键字被取消资格
- 函数返回类型和名称之间存在未知关键字
- 返回类型后的静态关键字
- 返回指向 const 数据成员和 'auto' 关键字的 const 指针。有点困惑
- 作为返回类型的枚举关键字的存在表明什么
- 返回类型 - C++ "class"关键字
- 静态关键字保存函数返回的值
- Gcc 4.8.3 没有发现缺少的"返回"关键字
- 在后面的返回类型函数语法中,auto关键字背后是否有意图
- 为什么VC++2013拒绝编译嵌套类型,当用作模板函数返回类型时,用using关键字使其可见
- 从constexpr函数返回一个类需要使用g++的virtual关键字
- 如果我在互斥锁之间声明一个变量并返回它,我需要使用volatile关键字吗?
- C++11-清除返回值语法和decltype关键字
- 如何在c++ 11中使用auto关键字返回任意类型
- 函数声明返回类型中的Const关键字
- 为什么new关键字返回指针而不是引用
- 如果我们在c++中使用static关键字删除[-Wreturn local-addr](警告:返回本地变量的地址),可以