Frage

Session Transkript:

>type lookma.c
int main() {
  printf("%s", "no stdio.h");
}

>cl lookma.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

lookma.c
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:lookma.exe
lookma.obj

>lookma
no stdio.h
War es hilfreich?

Lösung

In strikter Übereinstimmung Modus (das bedeutet „in der Theorie“), können Sie nicht definiertes Verhalten aufrufen (was schlecht ist), wenn Sie eine Funktion aufrufen, die eine variable Anzahl von Argumenten ohne Prototyp Erklärung der Funktion im Umfang erfolgt. Das bedeutet, dass die Compiler etwas zu tun erlaubt ist, es mit einem Programm, das mag printf() ohne den Prototyp von #include <stdio.h> oder einer gleichwertigen Erklärung verwendet. „Alles, was es mag“ schließt richtig als eine der Optionen arbeiten; das scheint die Option gewählt von Ihrem Beispiel zu sein.

In der Praxis wird der Code OK arbeiten mit den meisten praktischen Compiler auch ohne die formelle Erklärung der printf() Funktion.

Wie von qrdl weist darauf hin, wurde die Funktion gefunden, weil die C-Compiler-Links mit der C-Bibliothek.

Beachten Sie, dass Chris Young Kommentar über C99 und ‚implizites int‘ genau ist, sondern die Regel etwa gilt sowohl für C89 und C99 ‚variable Argumente Funktionen einen Prototyp in Umfang haben müssen‘. Die meisten Compiler arbeiten nicht in einem strengen C99-Kompatibilitätsmodus standardmäßig, weil es zu viel Code, der nicht so kompilieren würde.

Chris Young kommentierte:

  

Um zu klären, mein Kommentar war auf C99 Entfernen implizite Erklärungen. Indem man sagt, „implizite int“, ich glaube, Sie auf die C89-Funktion zuzulassen Erklärungen beziehen sich wie foo (void); bedeuten int foo (void) ;, etwas C99 ebenfalls entfernt.

Chris ist natürlich richtig. Es gab zwei ‚implizite Deklaration‘ -Funktionen aus dem C99-Standard entfernt. Das Vorwort der Norm listet sie als:

  • entfernen impliziten int
  • entfernt implizite Funktionsdeklaration

Ich war nicht zu denken (und damit das Schreiben nicht) klar genug. Dennoch beide C89 und C99 erfordern einen Prototyp in Rahmen für Funktionen, die eine variable Anzahl von Argumenten entgegennehmen.

Zur Veranschaulichung:

extern int pqr();
int main(void)
{
    int i = pqr(1, 3);
    return i;
}

, ohne die ersten Linie ist dies ein korrektes C89-Fragment mit einer impliziten Deklaration der Funktion pqr() als eine Funktion, die eine ganze Zahl zurückzugibt (mit nicht spezifizierten Argumenten). Wenn die erste Zeile von extern pqr(); ersetzt wird, dann ist dies ein korrektes C89-Fragment mit einer expliziten Erklärung pqr() als eine Funktion, die eine ganze Zahl (mit nicht spezifizierten Argumenten) gibt, aber der Rückgabetyp ist ‚implizites int‘. Wie schon geschrieben, wird die Funktion explizit deklariert und hat einen expliziten int Rückgabetyp - aber es hat noch nicht näher bezeichnet Argumente. Ich glaube, das gilt C99 - wenn auch nicht ganz wünschenswert. Sicherlich GCC (3.4.4) nimmt es mit den Optionen -std=c99 -pedantic“. Idealerweise ist die Funktionsdeklaration sollte den vollständigen Prototyp enthalten. (Und wenn pqr() mit Auslassungspunkte definiert wurden, wäre das Prototyp erforderlich in Theorie !)

Andere Tipps

Sie hatte ursprünglich markiert diesen C ++, aber es scheint, ein C-Programm zu sein. C wird automatisch eine implizite Deklaration für eine Funktion zur Verfügung stellen, wenn es keinen Prototyp in ihrem Umfang ist (wie zum Beispiel durch den Wegfall von #include ). Die implizite Erklärung wäre:

int printf();

Was bedeutet, dass printf ist eine Funktion, die einen int zurückgibt und eine beliebige Anzahl von Argumenten entgegennehmen können. Dieser Prototyp geschah für Ihren Anruf zu arbeiten. Sie sollten #include

Schließlich, soll ich hinzufügen, dass der aktuelle C-Standard (ISO / IEC 9899: 1999 oder umgangssprachlich "C99") hat nicht erlauben implizite Erklärungen, und dieses Programm nicht entsprechen. Implizite Erklärungen wurden entfernt. Ich glaube, Ihr Compiler nicht C99 unterstützt. C ++ erfordert auch richtig Prototypen und macht keine implizite Erklärungen.

printf() wird in Standard-C-Bibliothek und Linker befindet verbindet immer Standardbibliothek auf die ausführbare Datei, so werden alle Standardfunktionen gefunden werden und es wird keine Verknüpfung Probleme.

Failure entsprechende Header-Ergebnisse enthalten Funktion verwenden, die nicht prototypisiert wurde, die zu Problemen führen kann, wie C-Compiler diese Funktion übernimmt, ohne Prototyp int zurückgibt und variable Anzahl von Argumenten. Also immer Include Header -. Es ist Ihr Sicherheitszaun

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