为什么使用switch语句的函数不需要返回

问题描述:

enum MyEnum 
{ 
    A, 
    B, 
} 

MyEnum Foo(int i) 
{ 
    MyEnum mx; 
    switch(i) 
    { 
    case 1: 
     { 
      mx = A; 
     }break; 
    case 2: 
     { 
      mx = B; 
     }break; 
    default: 
     { 
      throw std::exception("ERROR"); 
     } 
    } 
} 

int Main() 
{ 
    MyEnum myEnum = Foo(1); 
    return 0; 
} 

如果Foo()中没有'return',则此代码可以在VS2010中编译和运行。它是编译器错误吗?为什么使用switch语句的函数不需要返回

VS2010 screenshot,以确认它可以运行

+3

*警告:函数中没有返回语句返回非void [-Wreturn-type] * http://liveworkspace.org/code/3898ddcf0e5b69eb23763ddf2ba56f51 – chris

+3

不,这是您的代码和开发实践中的一个错误,无法编译在最高的警戒级别。 –

+0

感谢您的所有评论, 根本原因是** default ** case引发异常,然后编译器将其视为有效的退出点。 如果我在** switch case **之后添加一些代码,编译器报告'警告C4715:'Foo':并非所有的控制路径都返回一个值'。 如果我删除**默认**,或不返回或抛出**默认**,编译器报告错误C4716:'Foo':必须返回一个值'。 –

它不是一个编译器错误。缺少的返回不需要编译器的诊断(但编译器可能会发出一个),并导致未定义的行为 - 任何事情都可能发生。

+3

没有返回语句的函数是完全有效的,不管返回类型如何,如果函数永不返回。例如,到达函数的闭包(可能有一些你不应该依赖的异常)是无效的,但是在函数结尾处无条件地调用abort()也是有效的。我知道这就是你的意思,但细微的差别是很重要的,因为它解释了为什么编译器不能/不应该只在没有返回语句时发出无条件警告。 – hvd

+0

@BeersonicPasagorn如果没有返回,那么编译器会更容易告诉函数永远不会返回。但是,即使那样,我也不认为需要诊断。 –

+0

只要删除**默认**或**抛出异常**,然后编译器可以报告'返回缺少' –