Weiß jemand, warum das Kompilieren erfolgreich ist?

8

Jeder weiß, warum das erfolgreich in C kompiliert?

%Vor%

Ich dachte, wenn die Deklaration nicht angegeben wird C nehme an extern int Function_name(arg1,arg2,...){}. Das sollte also einen Fehler geben, aber es funktioniert! Ich weiß, dass Ideone die Warnungen unterdrückt, aber meine Frage ist, warum gibt es keinen geraden Fehler? (aber in C ++ ist es ein direkter Fehler)

    
Quixotic 19.11.2012, 12:47
quelle

5 Antworten

8

Erhöhen Sie die Warnstufe in Ihrem Compiler und Sie sollten 2 Warnungen erhalten,

display nicht deklariert, int angenommen

und

display redeclared

Bearbeiten:

Ältere Versionen von C (vor C99) kümmern sich nicht wirklich um Rückgabetypen oder Argumenttypen. Man könnte sagen, dass es Teil des K & amp; R Vermächtnisses ist. Wenn Sie beispielsweise die Argumenttypen nicht explizit angeben, überprüft der Compiler sie überhaupt nicht.

C ++ ist strenger, was IMO ist eine gute Sache. Ich liefere immer Deklarationen und gebe immer die Argumentlisten an, wenn ich in C eincodiert habe.

    
Klas Lindbäck 19.11.2012 12:52
quelle
5

Es wird kompiliert, weil C viele Standardwerte verwendet, um rückwärtskompatibel zu sein. In K & amp; R C konnten Sie keine Funktionsprototypen angeben, daher würde der Compiler einfach davon ausgehen, dass Sie wissen, was Sie tun, wenn Sie eine Funktion aufrufen.

Später (zumindest ANSI C, aber vielleicht sogar in C99), hatte C nicht wirklich eine Möglichkeit,

zu unterscheiden %Vor%

also muss die leere Deklaration ebenfalls akzeptiert werden.

Deshalb können Sie display() aufrufen, ohne es zuerst zu definieren.

printf() ist ähnlich. Sie erhalten einen Linker-Fehler, wenn Sie -lc vergessen haben, aber aus Sicht des Compilers ist der Code "gut genug".

Das ändert sich, sobald Sie alle Warnungen aktivieren, die Ihr Compiler anbieten muss, und es wird mit einem Fehler fehlschlagen, wenn Sie die K & amp; C-Kompatibilität deaktivieren oder strenge ANSI-Prüfungen ermöglichen.

Aus diesem Grund wird "C" oft als "Sie schießen sich in den Fuß" in "Wie man schießen" aufgeführt Sich in den Fuß mit jeder Programmiersprache "Art von Listen.

    
Aaron Digulla 19.11.2012 12:53
quelle
3

es hängt von Ihrer Cx (C89, C90, C99, ...)

ab

für Funktionsrückgabewerte, vor C99 wurde explizit angegeben, dass der Übersetzer, wenn keine Funktionsdeklaration sichtbar war, einen zur Verfügung gestellt hat. Diese impliziten Deklarationen wurden standardmäßig auf den Rückgabetyp von int

zurückgesetzt

Begründung aus C-Standard (6.2.5 Seite 506)

  

Vor C90 gab es keine Funktionsprototypen. Entwickler erwartet zu   in der Lage sein, Argumente, die unterschrieben und nicht unterschrieben haben, auszutauschen   Versionen desselben Integer-Typs. Muss ein Argument werfen, wenn der   Parametertyp in der Funktionsdefinition hatte eine andere Signiertheit,   wurde als Gegenstück zu C's leichtgängigen Typ-Check-System gesehen und a   wenig aufdringlich. Die Einführung von Prototypen hat nicht vollständig getan   weg mit der Frage der Austauschbarkeit von Argumenten. Die Ellipse   Die Schreibweise besagt, dass über die Ellipse von 1590 nichts bekannt ist   liefert keine Informationen erwartete Art von Argumenten. In ähnlicher Weise, z   Funktion Rückgabewerte, vor C99 wurde explizit darauf hingewiesen   Wenn keine Funktionsdeklaration sichtbar war, stellte der Übersetzer eine zur Verfügung.   Diese impliziten Deklarationen wurden standardmäßig auf einen Rückgabetyp von int gesetzt. Wenn die   Die tatsächliche Funktion hat den Typ unsigned int zurückgegeben, wie z   Die Standarddeklaration hat möglicherweise ein unerwartetes Ergebnis zurückgegeben. Viel   Entwickler hatten eine lockere Haltung gegenüber Funktionserklärungen. Das   Die anderen müssen mit den Konsequenzen des Komitees nicht leben   Ich wollte den ganzen Quellcode, den sie geschrieben hatten, brechen. Das   Austauschbarkeit von Funktionsrückgabewerten ist jetzt ein strittiger Punkt,   weil C99 erfordert, dass eine Funktionsdeklaration am   Point of Call (eine Standarddeklaration wird nicht mehr bereitgestellt)

    
MOHAMED 19.11.2012 13:13
quelle
1

Es ist wahrscheinlich (nehmen Sie eine Erklärung an, wie Sie es geschrieben haben), aber da Sie keine Parameter übergeben, funktioniert es einfach. Es ist dasselbe wie wenn Sie int main() deklarieren, wo es eigentlich int main(int argc, char *argv[]) sein sollte.

Also wahrscheinlich, wenn Sie versucht haben, einige Parameter (anders als die Standardparameter) von main zu übergeben, dann verwenden Sie sie in display , es würde fehlschlagen.

BTW, für mich kompiliert es, aber erzeugt eine Warnung:

%Vor%     
kompas 19.11.2012 12:57
quelle
0

Wenn ich mit gcc kompiliere, erhalte ich wie erwartet Warnungen über die Deklaration von display .

Haben Sie Warnungen erhalten?

Es könnte "ausgeführt" werden, weil C keine Funktionsnamen (wie C ++) enthält. Der Linker sucht also nach einem Symbol 'display' und findet einen. Der Linker verwendet diese Adresse, um display auszuführen. Ich würde erwarten, dass Ergebnisse nicht das sind, was Sie die ganze Zeit erwarten.

    
Starkey 19.11.2012 12:54
quelle

Tags und Links