2011-05-08 31 views
24

有人可以向我解釋爲什麼下面的代碼沒有警告或錯誤編譯?C函數沒有參數行爲

我希望編譯器警告我,函數測試不期望任何參數。 但代碼編譯並遞歸運行功能測試。

#include <stdio.h> 
#include <stdlib.h> 

static void test1(int a, int b, int c) {} 

static void test() { 
    printf("HERE\n"); 
    test(1,2,3); 
} 

void main() { 
    test(); 
} 
+4

@Chris是的。爲什麼哦,爲什麼當人們在這裏發帖時,他們的示例代碼如此血腥難以閱讀。使用完全不同的名稱而非幾乎相同的名稱有什麼不妥?請別人使用「test」和「test1」等名稱,使用「A」,「B」和「C」等名稱。 – 2011-05-08 19:29:27

+0

除了正確的答案表明一組空參數不是C中的原型,您可以使用'-Wstrict-prototypes'在GCC中啓用缺少原型的警告,在MSVC中使用'/ Wall/W4' 。請注意'-Wall'不能在GCC中啓用這個警告(我不知道爲什麼)。 – 2011-05-08 20:21:21

+0

糟糕,當我打算拒絕這個問題時,我批准了這個問題的編輯。 – 2011-05-09 13:31:53

回答

45

在C++中,void test()聲明瞭一個不帶參數的函數(並且不返回任何內容)。

在C中,void test()聲明瞭一個函數,它接受一個未指定(但不是可變)數量的參數(並且不返回任何內容)。所以你所有的呼叫在C中都是有效的(根據原型)。

在C中,使用void test(void)來聲明一個真正不帶參數的函數(並且不返回任何內容)。

+0

你是什麼意思未指定(但不可變),我可以參考這些參數的功能? – 2011-05-08 19:28:09

+0

@John - 如果函數是帶參數的_defined_,是的。你必須做'void test(); int main(void){test(); } void test(int a,int b,int c){puts(「Yo」);測試(a,b,c); }(或將'test'放在單獨的文件中。) – 2011-05-08 19:32:38

+2

+1表示「未指定(但不可變)」; @John表示編譯器不會檢查參數的數量(或類型),但是您必須使用與定義中的參數匹配的參數來調用函數。請注意,定義和聲明不必在同一個文件中。在OP提供的例子中,'test'被定義爲沒有參數,雖然原型沒有強制它,但調用具有一個或多個參數的'test()'調用未定義的行爲 – pmg 2011-05-08 19:36:34

11

在聲明具有空參數列表的功能,可以調用ķ& R(預原型)的語義,並沒有什麼假定關於參數列表;這使得ANSI-C之前的代碼仍然可以編譯。如果要使用空參數列表的原型函數,請使用(void)而不是()