Domanda

Quando il mio programma è costituito da due file:

main.c

#include <stdio.h>

int main(void) { 
     printf("%lf\n",f());   
     return 0;
 }

func.c

double f(int a) {
 return 1;
}

compilatore non mostrano alcun errore.

Quando il mio programma si compone di un solo file:

main.c

#include <stdio.h>

int main(void) { 
     printf("%lf\n",f());   
     return 0;
 }

double f(int a) {
 return 1;
}

Visual C ++ 2008 compilatore mostrare il seguente errore:

Error 2 error C2371: 'f' : redefinition; different basic types d:\temp\projects\function1\function1\1.c 8 function1

Qualcuno può spiegare questo strano comportamento?

È stato utile?

Soluzione

Entrambi i programmi sono sbagliati.

Senza un prototipo di portata, un compilatore presuppone che una funzione restituisce int e richiede un numero imprecisato 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 cerchiamo di ignorare l'avviso.

$ 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

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 ancora compilato il codice, perché non poteva dire che f() non è stato definito il modo in cui è stato (implicitamente) ha dichiarato. Ma la compilazione del programma di cui sopra non è richiesto dallo standard, in modo che il compilatore avrebbe rifiutato (provate 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 respingere il programma di cui sopra, si può o non può.

La maggior parte dei compilatori non rifiutano il primo programma, perché non so se si dispone di una corretta definizione della funzione f() in un'altra unità di traduzione o no. Rifiutano il secondo programma perché sa che non lo fanno.

Altri suggerimenti

C assumerà una funzione ha il prototipo int func (); a meno che non hai detto altrimenti. (Si noti che in C int func () e int func (void); sono cose diverse)

Nel vostro secondo caso, si fa una chiamata a f() per cui il compilatore non ha visto alcun prototipo, quindi si presuppone che è int f();. Più tardi si vede la tua definizione per f() che ha un prototipo diverso -. Ed emette un errore

Questo non accade nel 1. caso, come sono in diverse unità di compilazione.

Il primo esempio non usa mai func.c quindi non sono sicuro di quello che il compilatore sta facendo su f() perché non ha alcuna definizione.

Nel secondo esempio, non so il motivo per cui non è possibile avere due funzioni con firme diverse, ma non si sta chiamando la funzione che hai definito. Si chiama f() senza argomenti, ma il f si definisce prende un int che lo rende una funzione diversa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top