与Java不同,在C / C ++中,允许:
int* foo ()
{
if(x)
return p;
// what if control reaches here
}
这通常会导致崩溃并且难以调试问题。为什么标准不强制执行非void
函数的最终返回? (编译器为错误的return
值生成错误)
gcc / msvc中是否有任何标志强制执行此操作? (类似于-Wunused-result
)
答案 0 :(得分:12)
在-Wall
中使用gcc
标记。
warning: control reaches end of non-void function
编辑:或更具体地说是-Wreturn-type
。
答案 1 :(得分:9)
不允许(未定义的行为)。但是,在这种情况下,标准不需要诊断。
标准不要求最后一个语句为return
,因为代码如下:
while (true) {
if (condition) return 0;
}
这总是返回0,但是一个愚蠢的编译器看不到它。请注意,该标准并未强制要求使用智能编译器。在return
块之后的while
语句将是一个浪费,而愚蠢的编译器将无法优化。该标准不希望程序员编写废弃代码只是为了满足一个愚蠢的编译器。
g ++ -Wall非常聪明,可以在我的机器上发出诊断信息。
答案 2 :(得分:3)
我的猜测:因为有时程序员比编译器更了解。有了这个简单的例子,显然有些错误,但考虑转换许多值,或者通常进行多次检查。作为编码人员,你知道某些值不会被传递给函数,但是编译器没有,只是提示你,可能存在错误。
#include <iostream>
int foo(){
if(false)
return 5;
}
int main(){
int i = foo();
std::cout << i;
}
请注意,MSVC上的even warning level 1会发出以下警告:
警告C4715:'foo':并非所有控制路径都返回值
答案 3 :(得分:1)
AFAIR Visual Studio 2008警告您“没有返回值的执行路径”。允许的意思是“C ++不会阻止你在脚下射击你”。所以你要思考,而不是编译器。
答案 4 :(得分:1)
显而易见的答案是:因为这不是错误。这只是一个错误
x
为false,如果调用者使用返回值,则两者都不是
必须由编译器确定,至少在一般情况下
情况下。
在这种特殊情况下(返回一个指针),它也不会
所有路径都难以return
; Java这样做。在
但是,在C ++中要求这样做是不合理的,因为在
C ++,您可以返回可能无法使用的用户定义类型
构造一个值(没有默认构造函数等)所以我们有了
程序员可能无法提供return
的情况
在他或她知道不能采取的分支中,编译器不能
确定不能采取分支。
大多数编译器会在这种情况下发出警告,以确定流量。 我所见过的所有人在某些情况下也会发出警告 然而,不可能失败。 (g ++和VC ++都警告说:
int
bar( char ch )
{
switch ( ch & 0xC0 ) {
case 0x00:
case 0x40:
return 0;
case 0x80:
return -1;
case 0xC0:
return 1;
}
}
,至少是通常的选择。虽然这很清楚 功能永远不会结束。)
答案 5 :(得分:1)
答案 6 :(得分:0)
标准对此类编程的说法是它产生未定义的行为。
未定义的行为是C / C ++的乐趣和怜悯,但它也是语言设计的一个基本特征,允许许多低级优化使C成为一种“高级汇编程序”(它是不,实际上,只是为了给你一个想法)。
因此,在重定向到约翰关于转换为与GCC一起使用的答案的过程中,为了知道“为什么”标准并没有阻止这一点,我会指出一个非常有趣的分析未定义的行为及其所有的misteries:{{3 }}。这是一个非常有益的阅读。