Frage

Wenn mein Programm besteht aus zwei Dateien:

main.c

#include <stdio.h>

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

func.c

double f(int a) {
 return 1;
}

Compiler zeigen keine Fehler.

Wenn mein Programm besteht aus nur einer Datei:

main.c

#include <stdio.h>

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

double f(int a) {
 return 1;
}

Visual C ++ 2008-Compiler zeigen die folgenden Fehler:

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

Kann jemand dieses seltsame Verhalten erklären?

War es hilfreich?

Lösung

Beide sind die Programme falsch.

Ohne einen Prototyp in Rahmen, ein Compiler setzt voraus, dass eine Funktion kehrt int und nimmt eine nicht spezifizierte Anzahl von Parametern.

Lassen Sie uns ändern Sie Ihre Dateien ein bisschen:

$ 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;
}

Wenn ich es kompilieren, gcc warnt mich (Visual C ++ sollte auch in konformes-Modus). Aber lassen Sie uns die Warnung ignorieren.

$ 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

Es hat nicht 1 drucken, sondern gedruckt 0. Dies liegt daran, dass der Compiler, dass f() nahm eine int zurückgegeben, und die Zuordnung d = f(); umgewandelt, dass „int“ zu einem double. Der Compiler noch den Code kompiliert, weil es nicht, dass f() sagen konnte, nicht die Art und Weise definiert wurde, war es (implizit) erklärt. Aber das obige Programm Kompilierung erforderlich ist, nicht von der Norm, so dass der Compiler es abgelehnt haben könnte (versuchen Sie mit gcc -Werror zum Beispiel!)

Wenn wir alles in einer Datei haben:

$ 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'

Nun sieht der Compiler den Konflikt, und gibt Ihnen eine Fehlermeldung. Aber wird ein Compiler nicht erforderlich, um das obige Programm abzulehnen, es kann oder auch nicht.

Die meisten Compiler nicht ablehnen, das erste Programm, weil sie nicht wissen, ob Sie eine korrekte Definition der Funktion f() in einer anderen Übersetzungseinheit haben oder nicht. Sie lehnen das zweite Programm, weil sie wissen , dass Sie dies nicht tun.

Andere Tipps

C wird eine Funktion übernehmen hat den Prototyp int func (); es sei denn, Sie haben es anders gesagt. (Beachten Sie, dass in C int func () und int func (void); verschiedene Dinge sind)

In Ihrem zweiten Fall haben Sie einen Anruf an f(), für die der Compiler keinen Prototyp gesehen hat, so nimmt es int f(); ist. Später es sieht Ihre Definition für f(), die einen anderen Prototyp hat -. Und gibt einen Fehler

Dies geschieht nicht im 1. Fall, wie sie in verschiedenen Übersetzungseinheiten sind.

Ihr erstes Beispiel nie verwendet func.c so dass ich nicht sicher bin, was genau der Compiler über f() tut, weil es keine Definition hat.

Im zweiten Beispiel, ich weiß nicht, warum Sie nicht zwei Funktionen mit unterschiedlichen Signaturen aufweisen können, aber Sie rufen nicht die Funktion, die Sie definiert haben. Sie rufen f() ohne Argumente, aber die f Sie einen int definieren nimmt, die es eine andere Funktion macht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top