[英]C void function with return value
據我所知,void 函數中的return
語句會拋出錯誤。
但在下面的程序中,情況並非如此。
這里顯示的輸出是1
。 怎么會?
main()
{
int i=5;
printf("%d",fun(fun(fun(i))));
}
void fun(int i)
{
if (i%2)
{
return (i+(7*4)-(5/2)+(2*2));
}
else
{
return (i+(17/5)-(34/15)+(5/2));
}
}
沒有表達式的return
語句:
void func(void) {
return;
}
在void
函數中是完全合法的。 帶有表達式的return
語句的合法性取決於您使用的 C 語言版本。
1990 C 標准說:
帶有表達式的
return
語句不應出現在返回類型為void
的函數中。
該標准的 1999 年和 2011 年版本都說:
帶有表達式的
return
語句不應出現在返回類型為void
的函數中。 沒有表達式的return
語句只能出現在返回類型為void
的函數中。
這是一個約束,意味着編譯器必須為任何違反它的程序發出診斷(可能是非致命警告)。
由於歷史原因,C90 允許在非void
函數中使用沒有表達式的return
語句。 Pre-ANSI C 沒有void
關鍵字,因此無法定義不返回值的函數。 程序員會省略返回類型(默認為int
)並簡單地忽略它。 C90 規則允許這樣的舊代碼編譯而不會出錯。 您仍然可能無法從非void
函數返回值; 如果調用者嘗試使用(不存在的)結果,則程序的行為是未定義的。 1999 年的標准稍微收緊了規則。
你的程序的另一個問題是你在它的聲明可見之前調用了fun
。 根據 C99 和更高版本的規則,這是非法的(盡管編譯器可能只是對此發出警告)。 在 C90 規則下,這是合法的,但編譯器會假設函數返回int
。 您的程序的行為是未定義的,但您的void
函數fun
可能恰好表現得好像它返回了一個值,而對它的調用可能恰好表現得好像它使用了該值。
C 編譯器往往對某些錯誤相當寬松,因此不會拒絕舊代碼(有時在第一個實際標准發布之前編寫)。 但是您的編譯器至少應該警告您有關return
語句的信息,以及可能有關無效調用的信息。 您應該密切注意編譯器警告; 應該像對待致命錯誤一樣對待它們。 並且您應該使用選項來增加編譯器警告您的事情的數量。 如果您使用 gcc,請使用-std=c90
、 -std=c99
或-std=c11
以及-pedantic
來強制執行標准一致性。 您可以添加-Wall
-Wextra 以啟用更多警告。
由於各種原因,您提供的代碼實際上在 C99 中無效,但最痛苦的一個如下:
foo.c:5:17: warning: implicit declaration of function 'fun' is invalid in C99 [-Wimplicit-function-declaration]
printf("%d",fun(fun(fun(i))));
^
foo.c:8:6: error: conflicting types for 'fun'
void fun(int i)
^
foo.c:5:17: note: previous implicit declaration is here
printf("%d",fun(fun(fun(i))));
^
請注意,如果您為fun()
提供了一個函數原型,您確實應該這樣做,那么您將得到一組不同的錯誤:
foo.c:7:25: error: passing 'void' to parameter of incompatible type 'int'
printf("%d",fun(fun(fun(i))));
^~~~~~
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.