2012-07-25 9 views
20

Mi chiedo perché questo compilerà:Perché il prototipo e la definizione di una funzione in C possono differire?

int test(); 

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

Perché non sarà il compilatore emetterà alcun errore/avvertimento riguardo che (ho provato clang, gcc)? Se cambio il valore di ritorno non verrà compilato, ma gli argomenti potrebbero differire ?!

+1

possibile duplicato del [argomenti vuoto C] (http://stackoverflow.com/questions/693788/c-void-arguments) –

risposta

28

Se si cambia:

int test(); 

a:

int test(void); 

otterrete l'errore previsto:

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

Questo perché int test(); dichiara semplicemente una funzione che prende eventuali parametri (ed è quindi compatibile con la successiva definizione di test), mentre int test(void); è un prototipo di funzione reale che dichiara una funzione che prende non parametri (e che è non compatibile con la definizione successiva).

+3

+1, per dirla con la terminologia C-ish, 'int test()' semplicemente non è un prototipo ma solo una dichiarazione. –

+0

Ma tale comportamento sarà presto deprecato (o almeno questo è ciò che ci dice ISO C11). – AnArrayOfFunctions

15
int test(); 

in una dichiarazione di funzione, nessun parametro indica che la funzione accetta un numero non specificato di argomenti.

Questo è diverso

int test(void); 

che significa che la funzione richiede alcun argomento.

Una dichiarazione di funzione senza parametro è il vecchio stile C di dichiarazione di funzione; C segna questo stile come obsoleto e scoraggia il suo uso. In breve, non usarlo.

Nel tuo caso, è necessario utilizzare una dichiarazione di funzione con la dichiarazione parametro corretto:

int test(void *data); 
+0

mi dimentico sempre C lo fa! Anche se era "int test (void)", ma cross TU non è necessario che venga emessa una diagnostica. – Flexo

Problemi correlati