2012-07-25 11 views
20

Zastanawiam się, dlaczego ta zostanie skompilowany:Dlaczego prototyp i definicja funkcji w C mogą się różnić?

int test(); 

int main() { return test((void*)0x1234); } 
int test(void* data) { return 0; } 

Dlaczego nie kompilator emituje żadnego błędu/ostrzeżenia o tym (próbowałem szczęk, gcc)? Jeśli zmienię wartość zwracaną, nie zostanie ona skompilowana - ale argumenty mogą się różnić ?!

+1

możliwy duplikat [argumenty C void] (http://stackoverflow.com/questions/693788/c-void-arguments) –

Odpowiedz

28

przypadku zmiany:

int test(); 

do:

int test(void); 

dostaniesz oczekiwany błąd:

foo.c:4: error: conflicting types for ‘test’ 
foo.c:1: error: previous declaration of ‘test’ was here 

To dlatego int test(); prostu deklaruje funkcję, która zaczyna żadnych parametry (a zatem jest zgodny z kolejnym definicji test), natomiast int test(void); jest rzeczywisty prototyp funkcji, która deklaruje funkcję, która zaczyna nie parametry (i który jest , a nie kompatybilny z kolejną definicją).

+3

+1, aby określić go w terminologii C-ish, 'int test()' po prostu nie jest prototypem, a jedynie deklaracją. –

+0

Ale takie zachowanie będzie wkrótce przestarzałe (a przynajmniej tak brzmi ISO C11). – AnArrayOfFunctions

15
int test(); 

w deklaracji funkcji, żaden parametr nie oznacza, że ​​funkcja przyjmuje nieokreśloną liczbę argumentów.

Różni się to od

int test(void); 

co oznacza, że ​​funkcja nie ma argumentu.

Deklaracja funkcji bez parametru to stara deklaracja funkcji stylu C; C oznacza ten styl jako przestarzały i zniechęca do jego używania. Krótko mówiąc, nie używaj go.

W twoim przypadku, należy użyć deklarację funkcji z poprawną deklarację parametru:

int test(void *data); 
+0

Zawsze zapominam, że C to robi! Nawet jeśli był to "test int (void);" ale w przypadku TU nie ma wymogu wydania diagnozy. – Flexo

Powiązane problemy