3 Stimmen

Ist die Fehlanpassung des Prototyps einer C-Funktion lediglich eine Warnung

Bitte sehen Sie sich meine Codes unten an

#include <stdio.h>

void printOut()
{
 static int i = 0;
 if (i < 10)
 {
  printOut(i);
 }
}

int main(int argc, char *argv[])
{

  return 0;
}

Eigentlich kompiliert der Code gut mit mingw5 Compiler, die für mich seltsam ist, dann ändere ich auf Borland Compiler, ich bekomme eine Warnmeldung sagte, dass keine printOut Funktion Prototyp, ist dies nur eine Warnung? Was mehr ist, wird der Code gut ohne Pop-up-Fehler Windows ausgeführt.

6voto

Mysticial Punkte 451718

In C kann eine Funktion, die keine Parameter hat, trotzdem Parameter annehmen.

Deshalb lässt es sich kompilieren. Der Weg, um festzulegen, dass es keine Parameter nimmt, ist:

void printOut(void)

Dies ist der richtige Weg, ist aber weniger üblich, vor allem für diejenigen, die einen C++-Hintergrund haben.

5voto

Keith Thompson Punkte 240701

Das Verhalten Ihres Programms ist undefiniert, denn Sie definieren printOut() ohne Parameter, aber Sie rufen es mit einem Argument auf. Das müssen Sie ändern. Aber Sie haben es so geschrieben, dass der Compiler nicht benötigt wird, um das Problem zu diagnostizieren. (gcc, zum Beispiel, warnt nicht über die Parameterübereinstimmung, sogar mit -std=c99 -pedantic -Wall -Wextra -O3.)

Die Gründe dafür sind historisch bedingt.

Vor-ANSI C (vor 1989) gab es keine Prototypen; Funktionsdeklarationen konnten nicht den erwarteten Typ oder die Anzahl der Argumente angeben. Funktion Definition Andererseits werden die Parameter der Funktion angegeben, aber nicht so, dass der Compiler nicht übereinstimmende Aufrufe diagnostizieren kann. Eine Funktion mit einem int-Parameter könnte zum Beispiel so deklariert werden (z. B. in einer Header-Datei):

int plus_one();

und (z.B. in der entsprechenden .c-Datei) wie folgt definiert:

int plus_one(n)
int n;
{
     return n + 1;
}

Die Parameterinformationen waren in der Definition verborgen.

ANSI C fügte Prototypen hinzu, so dass der obige Text wie folgt geschrieben werden könnte:

int plus_one(int n);

int plus_one(int n)
{
    return n + 1;
}

Die Sprache unterstützte jedoch weiterhin die Deklarationen und Definitionen im alten Stil, um den bestehenden Code nicht zu zerstören. Sogar der kommende C201X-Standard erlaubt noch Funktionsdeklarationen und -definitionen aus der Zeit vor dem ANSI-Standard, obwohl diese schon seit 22 Jahren veraltet sind.

Nach Ihrer Definition:

void printOut()
{
    ...
}

verwenden Sie eine Funktionsdefinition im alten Stil. Sie besagt, dass printOut keine Parameter hat - aber der Compiler warnt Sie nicht, wenn Sie die Funktion falsch aufrufen. Innerhalb Ihrer Funktion rufen Sie sie mit einem Argument auf. Das Verhalten dieses Aufrufs ist undefiniert . Es könnte das fremde Argument stillschweigend ignorieren -- oder es könnte den Stack beschädigen und Ihr Programm auf schreckliche Weise zum Absturz bringen. (Letzteres ist unwahrscheinlich; aus historischen Gründen sind die meisten C-Aufrufkonventionen tolerant gegenüber solchen Fehlern).

Wenn Sie möchten, dass Ihre printOut()-Funktion keine Parameter hat et Sie wollen, dass der Compiler sich beschwert, wenn Sie es falsch aufrufen, definieren Sie es als:

void printOut(void)
{
    ...
}

Dies ist die einzig korrekte Art und Weise, es in C zu schreiben.

Wenn Sie diese Änderung einfach in Ihrem Programm vornehmen und dann einen Aufruf von printOut() en main() haben Sie es mit einer rekursiven Endlosschleife zu tun. Sie wollen wahrscheinlich printOUt() um eine int Argument:

void printOut(int n)
{
    ...
}

In C++ gelten jedoch andere Regeln. C++ wurde von C abgeleitet, aber mit weniger Sorge um die Abwärtskompatibilität. Als Stroustrup Prototypen zu C++ hinzufügte, ließ er die Deklarationen im alten Stil ganz fallen. Da es keine Notwendigkeit für einen Sonderfall gab void Markierung für parameterlose Funktionen, void printOut() in C++ sagt ausdrücklich, dass printOut hat keine Parameter, und ein Aufruf mit Argumenten ist ein Fehler. C++ erlaubt auch void printOut(void) für die Kompatibilität mit C, aber das wird wahrscheinlich nicht sehr oft benutzt (es ist selten sinnvoll, Code zu schreiben, der sowohl in C als auch in C++ gültig ist). C und C++ sind zwei verschiedene Sprachen; Sie sollten die Regeln für die Sprache befolgen, die Sie verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X