2010-08-01 164 views
50

我發現下面的代碼被採用Visual C++ 2008和GCC 4.3編譯器接受:返回無效的有效代碼?

void foo() 
{ 

} 

void bar() 
{ 
    return foo(); 
} 

我有點驚訝的是它編譯。這是一種語言功能還是它在編譯器中的錯誤? C/C++標準對此有何評論?

回答

66

它的C++

C++語言特徵(ISO 14882:2003)6.6.3/3

,類型爲「CV空隙」的表達式的return語句可以在功能僅用於用cv void返回類型;該表達式在函數返回給調用者之前被評估。

C(ISO 9899:1999)6.8.6.4/1

帶表達式的return語句不得出現在返回類型 是無效的功能。

+1

注意,許多編譯器可以編譯C和C++將提供C++規則作爲非標準擴展在編譯的C代碼,但是這不應該依賴如果你想要便攜。 – 2017-03-13 20:04:44

49

是的,它是有效的代碼。當您有模板功能時,這是必要的,以便您可以使用統一代碼。例如,

template<typename T, typename P> 
T f(int x, P y) 
{ 
    return g(x, y); 
} 

現在,g可能被重載以在第二個參數是某種特定類型時返回void。如果「返回無效」無效,則f的呼叫將會中斷。

+1

'T'不能爲空,因爲參數不能爲空。 – strager 2010-08-01 17:54:33

+0

謝謝,幾分鐘後我意識到自己已經給出了一個不好的例子。固定! – zvrba 2010-08-01 17:59:53

+3

此功能還會打開一個小陷阱:在void positive_action(int n){if(n <0)return;動作(N); [...]}',如果'action'返回void,那麼在'return'後面忘記分號將不會給出錯誤或警告,但現在''action''會被調用,當''''是負數時,而不是正數時。 – 2014-04-18 07:13:20

5

這是有效的,可以是非常有用的,例如當你想在返回前做一些錯誤處理創建情況更清晰的代碼:確實

void ErrRet(int code, char* msg) 
{ 
    // code logging/handling error 
} 
void f() 
{ 
    if (...) return ErrRet(5, "Error Message !"); 
    // code continue 
} 
1

有效。我用它經常輸入驗證宏:

#define ASSERT_AND_RETURN_IF_NULL(p,r) if (!p) { assert(p && "#p must not be null"); return r; } 

bool func1(void* p) { 
    ASSERT_AND_RETURN_IF_NULL(p, false); 
    ... 
} 

void func2(void* p) { 
    ASSERT_AND_RETURN_IF_NULL(p, void()); 
    ... 
}