2016-03-14 111 views
60

這個編譯沒有任何警告。在C和C++中返回void類型

這是合法的C和C++還是隻是在gcc和鏗鏘聲中工作?

如果它是合法的,C99之後它是否是一些新的東西?

void f(){ 

} 

void f2(){ 
    return f(); 
} 

更新

爲 「拉德雷克薩斯」 建議我嘗試這樣做:

$ gcc -Wall -Wpedantic -c x.c 
x.c: In function ‘f2’: 
x.c:7:9: warning: ISO C forbids ‘return’ with expression, in function returning void [-Wpedantic] 
    return f(); 

$ clang -Wall -Wpedantic -c x.c 
x.c:7:2: warning: void function 'f2' should not return void expression [-Wpedantic] 
     return f(); 
     ^ ~~~~~ 
1 warning generated. 

$ gcc -Wall -Wpedantic -c x.cc 
(no errors) 

$ clang -Wall -Wpedantic -c x.cc 
(no errors) 

更新

有人問這樣的結構是如何幫助。那麼語法糖或多或少。這裏是一個很好的例子:

void error_report(const char *s){ 
    printf("Error %s\n", s); 
    exit(0); 
} 

void process(){ 
    if (step1() == 0) 
     return error_report("Step 1"); 

    switch(step2()){ 
    case 0: return error_report("Step 2 - No Memory"); 
    case 1: return error_report("Step 2 - Internal Error"); 
    } 

    printf("Processing Done!\n"); 
} 
+9

投票重新開放;提出的複製只適用於C++。這也被標記爲C.(C和C++在使用'void'方面差別很大)。 – Bathsheba

+14

所以你要求C或C++?選擇一種語言。 – 2501

+8

注意:同時使用'gcc -Wall-Wpedantic -std = c99'和'-std = c11',你會得到一個警告:「warning:ISO C禁止'返回'帶表達式,返回void [-Wpedantic]的函數中。 – usr2564301

回答

67

C11,6.8.6.4 「的return聲明」:

A return statement with an expression shall not appear in a function whose return type is void .

沒有,你可能不會使用表達式,哪怕是void類型。

從同一文件的前言:

Major changes in the second edition included:

[...]

  • return without expression not permitted in function that returns a value (and vice versa)

因此,這是從C89的變化 - > C99(語言標準第二版),並從那時起一直如此。


C++ 14,6.6.3 「的return聲明」:

A return statement with an expression of non-void type can be used only in functions returning a value [...] A return statement with an expression of type void can be used only in functions with a return type of cv void; the expression is evaluated just before the function returns to its caller.

,您可以如果是void類型的使用表達式(這一直是從C++ 98開始有效)。

+1

「帶有void類型表達式的return語句只能用於具有cv void返回類型的函數中」爲什麼有人想編寫這樣的無意義代碼?而不是隻寫'void f2(){f(); }'。似乎在某個地方必須有理由,即使它是C++? – Lundin

+7

@Lundin:模板?我假設。看起來像<= C99也允許它,並且C++可能只是複製了該行爲。 – DevSolar

+0

但是,在C99之前,我相信它會導致未定義的行爲。這在C++中似乎不是這種情況。那麼爲什麼會有人使用一個無效模板,如果甚至允許的話? – Lundin

13

此代碼允許C++C

不允許從Return statement @ cppreference

In a function returning void, the return statement with expression can be used, if the expression type is void.


OTOH在C11 n1570規格草案:

Major cha在第二版nges包括:

return without expression not permitted in function that returns a value (and vice versa)

和6.8.6.4返回(return與表達函數,它返回一個void不允許)

A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void.

(即使該表達式的計算結果到void

+0

引用C++標準和可能的文檔是更好的,因爲允許構建哪個版本。 cppreference不是一個非常可靠的來源,許多代碼示例都有錯誤。 – chqrlie

+0

@chqrlie你能給我一個鏈接到代碼示例是wring @ en.cppreference的頁面嗎? –

+0

@MohitJain:只是一個例子:http://en.cppreference.com/w/c/string/byte/strncat用gcc 4.6編譯: 'main.cpp:31:1:warning: void函數[-Wreturn-type]'。自C99以來沒有錯誤,但風格不好。 – chqrlie

3

ISO/IEC 9899:201x委員會草案說明如下:

6.8.6.4 The return statement

Constraints

  1. return statement with an expression shall not appear in a function whose return type is void.

    A return statement without an expression shall only appear in a function whose return type is void .

因此,在C中是禁止的。


您需要使用-pedantic開關gcc它抱怨標準的違規行爲:

test.c: In function ‘f2’: 
test.c:6:12: warning: ISO C forbids ‘return’ with expression, in function returning void 
      [-Wpedantic] 
    return f(); 
1

標準C不支持這樣的結構:

C11 6.8.6.4: The return statement

Constraints

1 A return statement with an expression shall not appear in a function whose return type is void . A return statement without an expression shall only appear in a function whose return type is void .

沒有特別規定添加對於問題中的特例。有些C編譯器確實支持這種擴展(除非被指示符合C標準之一),但C11和以前的版本認爲它是違反約束的。

5

C++允許這樣的事情:

void f() 
{ 
    return void(); 
} 

雖然C沒有。這就是爲什麼如果您將其編譯爲ISO C而不是ISO C++時發出警告的原因。這正式描述爲:

A return statement with an expression of type void can be used only in functions with a return type of cv void

+0

它看起來是正確的,但兩個索賠的標準參考將是很好的。 – HolyBlackCat