Sind Prototypen erforderlich für alle Funktionen in C89, C90 oder C99?
Wirklich Standard-konform sind, müssen alle Funktionen in C (außer main) haben einen Prototyp, auch wenn Sie nur nach Ihrer definition in der gleichen übersetzungseinheit?
- Die Frage Muss declare function Prototyp in C? war einst vorgeschlagen, als ein Duplikat von diesem auf. Es muss einen starken Grund in der Nähe eine ältere Frage als Duplikat einer neueren eher als Umgekehrt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es hängt davon ab, was du damit meinst 'wirklich, standards-konforme'. Aber die kurze Antwort ist: "es ist eine gute Idee, um sicherzustellen, dass alle Funktionen haben einen Prototyp im Rahmen vor".
Mehr qualifizierte Antwort stellt fest, dass, wenn die Funktion akzeptiert eine variable Argumente (insbesondere die
printf()
Familie von Funktionen), dann ein Prototyp muss im Rahmen streng standards konform. Dies gilt für C89 (aus ANSI -) und C90 (ISO; das gleiche wie C89, außer für die Kapitel-Nummerierung). Andere als 'varargs' Funktionen, aber auch Funktionen, die Rückkehr einerint
müssen nicht deklariert werden, und Funktionen, die etwas anderes als einint
brauchen eine Erklärung, die zeigt, dass der Rückgabetyp müssen aber nicht den Prototyp der argument Liste.Beachten Sie jedoch, dass, wenn die Funktion übernimmt Argumente, die unter "normalen Aktionen" in der Abwesenheit von Prototypen (z.B. eine Funktion, eine
char
odershort
- beide sind umgewandeltint
; ernst, vielleicht, eine Funktion, einefloat
statt einerdouble
), dann wird ein Prototyp benötigt wird. Der standard wurde lax über diese zu ermöglichen alten C-code zu kompilieren, die unter standard-konformen Compiler; ältere code wurde nicht geschrieben, um die Sorge um die Sicherstellung, dass die Funktionen erklärt wurden, bevor Sie zu benutzen, und per definition, älteren code nicht Prototypen verwenden, da Sie nicht geworden, lieferbar in C, bis es einen standard.C99 verbietet 'implizit int'...das bedeutet, dass beide oddball Fällen wie '
static a;
' (einint
standardmäßig) und auch impliziten Funktionsdeklarationen. Diese genannten (zusammen mit etwa 50 weiteren wesentlichen änderungen) in dem Vorwort zur ISO/IEC 9899:1999,die vergleicht, der standard zu den vorherigen Versionen:
In ISO/IEC 9899:1990, §6.3.2.2 Funktionsaufrufe angegeben:
Dieser Absatz fehlt in der 1999 standard. Ich habe (noch) nicht verfolgt, die Veränderung in der Wortschwall, dass ermöglicht
static a;
im C90, und lässt es (diestatic int a;
) in C99.Beachten Sie, dass wenn eine Funktion ist statisch, es kann definiert werden, bevor es verwendet wird, und muss nicht vorangestellt werden, in einer Erklärung. GCC davon überzeugt werden können, witter, wenn eine nicht-statische Funktion definiert wird, ohne eine Erklärung voranstellen (
-Wmissing-prototypes
).Einen Prototyp ist eine Funktion, die Deklaration legt fest, dass die Typen der Parameter der Funktion.
Prä-ANSI-C (Sprache beschrieben durch die 1978 erste Auflage von Kernighan & Ritchie, "The C Programming Language") keinen Prototypen; es war nicht möglich, für eine Funktion Erklärung zu beschreiben, die Anzahl oder Typen der Parameter. Es war bis an den Aufrufer übergeben werden, die richtige Anzahl und Typ der Argumente.
ANSI-C eingeführt, die "Prototypen", Erklärungen, die angeben, dass die Typen der Parameter (ein feature entlehnt aus früh, C++).
Als von C89/C90 (ANSI-und ISO-Normen beschreiben die gleiche Sprache), es ist legal, eine Funktion aufzurufen, ohne sichtbare Erklärung; eine implizite Deklaration vorgesehen ist. Wenn die implizite Deklaration ist nicht kompatibel mit der tatsächlichen definition (sagen wir, ruft
sqrt("foo")
, dann ist das Verhalten undefiniert. Weder das implizite Deklaration noch eine nicht-Prototyp-Deklaration, die kompatibel sein können mit einer variadischen Funktion, so dass jeder Aufruf einer Variable Funktion (wieprintf
oderscanf
) muss eine sichtbare Prototyp.C99 sank die implizite Deklarationen. Jeder Aufruf einer Funktion ohne sichtbare Erklärung ist eine constraint-Verletzung, die eine compiler-Diagnose. Aber diese Erklärung ist noch nicht erforderlich zu sein, ein Prototyp, es kann sein, ein old-style-Deklaration nicht angeben, parameter-Typen.
C11 gemacht keine signifikanten Veränderungen in diesem Bereich.
So, ja, wie der 2011 ISO-C-standard, old-style-Funktionsdeklarationen und-Definitionen (die "veraltete" seit 1989) sind noch erlaubt in konformen code.
Für alle Versionen von C geht auf das Jahr 1989 zurück, als eine Frage des Stils, es gibt sehr wenig Grund, nicht zu verwenden, Prototypen für alle Funktionen. Old-style-Deklarationen und Definitionen sind gehalten, nur um zu vermeiden, brechen alte code.
<stdarg.h>
und explizite variadischen Funktionen eingeführt wurden. Ein Beispiel von dem, was Sie sprechen, das ist der POSIX -open()
Funktion, die traditionell dauert Sie 2 oder 3 Argumente; POSIX gibt es so eine Variable Funktion. Die Frage ist, C89/C90 und C99, die vorher nicht-ANSI-C.printf()
scheitert an einer fehlenden Prototyp? In anderen Worten, was bedeutet "muss sichtbar Prototyp" bedeuten? (int main(void){int i = 1; printf("%d", i); }
)gcc -std=c11 -pedantic-errors
.#error
Richtlinie, das ist so nah wie die C-standard bekommt, um zu sagen, etwas ist illegal. Wenn ein compiler nicht ab das Programm, dessen Verhalten wird nicht durch eine Norm definiert. Ihre Frage ist über das Verhalten von einem bestimmten compiler. Wenn Sie neugierig sind, könnten Sie die post eine neue Frage (obwohl der beste Rat ist, einfach "Mach das nicht.")int printf();
, das Verhalten ist undefiniert, aber keine Diagnose erforderlich ist. Also nicht So tun, dass entweder.Nein, Funktionen müssen nicht immer ein Prototyp. Die einzige Voraussetzung ist, dass eine Funktion sein, die sich "erklärt", bevor Sie es verwenden. Es gibt zwei Möglichkeiten zum deklarieren einer Funktion: schreiben eines Prototyps, oder schreiben Sie selbst die Funktion (genannt "definition.") Eine definition ist immer auch eine Deklaration, aber nicht alle Deklarationen sind Definitionen.
int
Funktion, deren Argumente genau aufeinander abgestimmt, was war mit dem Aufruf übergeben, vorausgesetzt, die standard-Aktionen. Solche Compiler würde in der Regel geben einen Fehler aus, wenn eine Erklärung fand sich in der selben compilation unit, der im Widerspruch zu der, abgeleitet wurde. Wenn keine Erklärung gefunden wurde, und die argument-Typen nicht richtig (verglichen mit einer separat kompilierten Funktions-definition), das problem möglicherweise oder möglicherweise nicht erkannt werden zur link-Zeit.foo
wird aufgerufen mit Parameter inkonsistent mit der definition, die das Verhalten undefiniert. Zum Beispiel, wennfoo
definiert ist, mit 2int
Parameter, der Aufruf mit 3foo
Parameter hat Undefiniertes Verhalten. Was auch immer Sie versuchen zu tun, diese nicht-portable hack, es gibt eine bessere und mehr Tragbarer Art und Weise, es zu tun.Ja, jede Funktion muss ein Prototyp, aber das Prototyp erscheinen kann entweder in einer gesonderten Erklärung oder als Teil der Funktionsdefinition. Funktionsdefinitionen geschrieben in C89 und bis natürlich Prototypen, aber wenn Sie schreiben Dinge, die in den klassischen K&R Stil, also:
dann die definition der Funktion hat keinen Prototyp. Wenn Sie schreiben, ANSI C (C89) - Stil, also:
dann die definition einer Funktion hat eine prototype.
Einen netten Tipp beim schreiben von neuen Funktionen, um Ihnen zu schreiben upside-down mit main auf dem Boden, so dass, wenn Sie Ihre Meinung ändern über die Funktion die Argumente oder return-Typ, den Sie nicht lösen können, den Prototyp zu. Ständig zur Festsetzung von Prototypen, und den Umgang mit allen compiler-Warnungen, wenn Sie veraltet sind wirklich mühsam.
Sobald Sie Ihre Funktionen arbeiten reibungslos zusammen, um den code auf einem gut namens Modul und setzen Sie die Prototypen ein .h-Datei mit dem gleichen Namen. Es spart schweren Zeit. Die größte Produktivität Hilfe, die ich gefunden habe in 5 Jahren.
Meinem besten wissen (in ANSI-C89/ISO-C90), Nein. Ich bin nicht sicher C99; allerdings würde ich erwarten, dass die gleichen.
Persönliche Anmerkung: ich Schreibe nur Funktionsprototypen, wenn...
void func(int n) { /* ... */ }
umfasst ein Prototyp.