2012-10-22 112 views
2
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':必須返回一個值'。 –

回答

8

它不是一個編譯器錯誤。缺少的返回不需要編譯器的診斷(但編譯器可能會發出一個),並導致未定義的行爲 - 任何事情都可能發生。

+3

沒有返回語句的函數是完全有效的,不管返回類型如何,如果函數永不返回。例如,到達函數的閉包(可能有一些你不應該依賴的異常)是無效的,但是在函數結尾處無條件地調用abort()也是有效的。我知道這就是你的意思,但細微的差別是很重要的,因爲它解釋了爲什麼編譯器不能/不應該只在沒有返回語句時發出無條件警告。 – hvd

+0

@BeersonicPasagorn如果沒有返回,那麼編譯器會更容易告訴函數永遠不會返回。但是,即使那樣,我也不認爲需要診斷。 –

+0

只要刪除**默認**或**拋出異常**,然後編譯器可以報告'返回缺少' –

相關問題