Entrambi i programmi sono errati.
Senza un prototipo in ambito, un compilatore presuppone che una funzione restituisca int
e utilizzi un numero non specificato di parametri.
Cambiamo i file un po ':
$ cat func.c
double f(int a) {
return 1.0;
}
$ cat main.c
#include <stdio.h>
int main(void) {
double d = f();
printf("%lf\n", d);
return 0;
}
Quando compilo che, gcc mi avverte (Visual C++ dovrebbe troppo, in modo conforme). Ma ignoriamo l'avvertimento.
$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test
func.c:1: warning: unused parameter 'a'
main.c: In function 'main':
main.c:4: warning: implicit declaration of function 'f'
$ ./test
0.000000
E non è stato stampato 1, ma stampato 0. Questo è perché il compilatore presume che f()
restituito un int
, e l'assegnazione d = f();
convertito che "int
" ad un double
. Il compilatore ha ancora compilato il codice perché non è stato possibile stabilire che f()
non è stato definito come dichiarato (implicitamente). Ma la compilazione del programma di cui sopra non è richiesta dallo standard, quindi il compilatore potrebbe averlo respinto (prova con gcc -Werror
per esempio!)
Se abbiamo tutto in un unico file:
$ cat func.c >>main.c
$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test
main.c:4: warning: implicit declaration of function 'f'
main.c: At top level:
main.c:9: error: conflicting types for 'f'
main.c:4: error: previous implicit declaration of 'f' was here
main.c:9: warning: unused parameter 'a'
Ora il compilatore vede il conflitto, e ti dà un messaggio di errore. Ma un compilatore non è tenuto a rifiutare il programma di cui sopra, può o non può.
La maggior parte dei compilatori non rifiuta il primo programma perché non sa se si ha una definizione corretta della funzione f()
in un'altra unità di traduzione o meno. Rifiutano il secondo programma perché lo sa che non lo si fa.
fonte
2010-02-18 09:04:20
come ho capito: nel primo caso il linker è responsabile per l'associazione della chiamata della funzione con la sua definizione; nel secondo caso il compilatore è responsabile per l'associazione della chiamata della funzione con la sua definizione. Ho ragione? –