Frage
Ich habe eine Bibliothek erstellt,
mylib.c:
#include <mylib.h>
int
testlib() {
printf("Hello world\n");
return (0);
}
mylib.h:
#include <stdio.h>
extern int testlib();
In meinem Programm habe ich versucht, diese Bibliotheksfunktion aufzurufen:
meinprogramm.c:
#include <mylib.h>
int
main (int argc, char *argv[]) {
testlib();
return (0);
}
Wenn ich versuche, dieses Programm zu kompilieren, erhalte ich die folgende Fehlermeldung:
In file included from myprogram.c:1 mylib.h:2 warning: function declaration isn't a prototype
Ich benutze: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
Meine Frage ist: Wie deklariert man einen Funktionsprototyp richtig?
Lösung
In C int foo()
Und int foo(void)
sind unterschiedliche Funktionen. int foo()
akzeptiert eine beliebige Anzahl von Argumenten, while int foo(void)
akzeptiert 0 Argumente.In C++ bedeuten sie dasselbe.Ich schlage vor, dass Sie es verwenden void
konsequent, wenn Sie keine Argumente meinen.
Wenn Sie eine Variable haben a
, extern int a;
ist eine Möglichkeit, dem Compiler das mitzuteilen a
ist ein Symbol, das möglicherweise in einer anderen Übersetzungseinheit vorhanden ist (der C-Compiler spricht für Quelldatei), lösen Sie es erst zum Zeitpunkt der Verknüpfung auf.Andererseits werden Symbole, die Funktionsnamen sind, ohnehin zum Linkzeitpunkt aufgelöst.Die Bedeutung eines Speicherklassenspezifizierers für eine Funktion (extern
, static
) wirkt sich nur auf seine Sichtbarkeit aus und extern
ist die Standardeinstellung, also extern
ist eigentlich unnötig.
Ich schlage vor, das zu entfernen extern
, es ist irrelevant und wird normalerweise weggelassen.
Andere Tipps
Schnelle Antwort:ändern int testlib()
Zu int testlib(void)
um anzugeben, dass die Funktion keine Argumente akzeptiert.
A Prototyp ist per Definition eine Funktionsdeklaration, die die Art(en) der Argumente der Funktion angibt.
Eine Nicht-Prototyp-Funktionsdeklaration wie
int foo();
ist eine Deklaration im alten Stil, die weder die Anzahl noch die Art der Argumente angibt.(Vor dem ANSI-C-Standard von 1989 war dies die einzige Art von Funktionsdeklaration, die in der Sprache verfügbar war.) Sie können eine solche Funktion mit einer beliebigen Anzahl von Argumenten aufrufen, und der Compiler muss sich nicht beschweren – aber wenn die Der Anruf stimmt nicht mit dem überein Definition, Ihr Programm weist ein undefiniertes Verhalten auf.
Für eine Funktion, die ein oder mehrere Argumente akzeptiert, können Sie den Typ jedes Arguments in der Deklaration angeben:
int bar(int x, double y);
Ein Sonderfall sind Funktionen ohne Argumente.Logischerweise wären leere Klammern eine gute Möglichkeit gewesen, ein Argument anzugeben, aber diese Syntax wurde bereits für Funktionsdeklarationen im alten Stil verwendet, weshalb das ANSI-C-Komitee eine neue Syntax unter Verwendung von erfunden hat void
Stichwort:
int foo(void); /* foo takes no arguments */
Eine Funktion Definition (einschließlich Code für das, was die Funktion tatsächlich tut) bietet auch a Erklärung.In Ihrem Fall haben Sie etwas Ähnliches wie:
int testlib()
{
/* code that implements testlib */
}
Dies stellt eine Nicht-Prototyp-Deklaration für dar testlib
.Als Definition sagt dies dem Compiler das testlib
hat keine Parameter, aber als Deklaration teilt es dem Compiler dies nur mit testlib
akzeptiert eine nicht spezifizierte, aber feste Anzahl und Art(en) von Argumenten.
Wenn du dich änderst ()
Zu (void)
Die Deklaration wird zum Prototyp.
Der Vorteil eines Prototyps besteht darin, dass er nicht versehentlich aufgerufen wird testlib
Mit einem oder mehreren Argumenten diagnostiziert der Compiler den Fehler.
(C++ hat etwas andere Regeln.In C++ gibt es keine Funktionsdeklarationen im alten Stil, und leere Klammern bedeuten insbesondere, dass eine Funktion keine Argumente akzeptiert.C++ unterstützt das (void)
Syntax für Konsistenz mit C.Sofern Sie Ihren Code jedoch nicht ausdrücklich zum Kompilieren sowohl in C als auch in C++ benötigen, sollten Sie wahrscheinlich die verwenden ()
in C++ und die (void)
Syntax in C.)
Versuchen:
extern int testlib(void);