déclaration de fonction n’est pas un prototype

J’ai une bibliothèque que j’ai créée,

mylib.c:

#include  int testlib() { printf("Hello world\n"); return (0); } 

mylib.h:

 #include  extern int testlib(); 

Dans mon programme, j’ai tenté d’appeler cette fonction de bibliothèque:

myprogram.c:

 #include  int main (int argc, char *argv[]) { testlib(); return (0); } 

Lorsque je tente de comstackr ce programme, j’obtiens l’erreur suivante:

  Dans le fichier inclus à partir de myprogram.c: 1
 mylib.h: 2 avertissement: la déclaration de fonction n'est pas un prototype 

J’utilise: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)

Ma question est la suivante: quelle est la bonne façon de déclarer un prototype de fonction?

Dans C int foo() et int foo(void) sont des fonctions différentes. int foo() accepte un nombre arbitraire d’arguments, alors que int foo(void) accepte 0 arguments. En C ++, ils signifient la même chose. Je suggère que vous utilisez systématiquement le void lorsque vous ne voulez dire aucun argument.

Si vous avez une variable a , extern int a; est un moyen de dire au compilateur que a est un symbole qui peut être présent dans une autre unité de traduction (le compilateur C parle pour le fichier source), ne le résout pas avant la connexion. En revanche, les symboles qui sont des noms de fonction sont résolus au moment de la liaison. La signification d’un spécificateur de classe de stockage sur une fonction ( extern , static ) n’affecte que sa visibilité et extern est la valeur par défaut, donc extern est en fait inutile.

Je suggère de supprimer l’ extern , il est étranger et est généralement omis.

Réponse rapide: changez int testlib() en int testlib(void) pour spécifier que la fonction ne prend aucun argument.

Un prototype est par définition une déclaration de fonction qui spécifie le ou les types d’arguments de la fonction.

Une déclaration de fonction non prototype comme

 int foo(); 

est une déclaration de style ancien qui ne spécifie pas le nombre ou les types d’arguments. (Avant la norme ANSI C de 1989, c’était le seul type de déclaration de fonction disponible dans le langage.) Vous pouvez appeler une telle fonction avec un nombre arbitraire d’arguments, et le compilateur n’est pas obligé de se plaindre – mais si le call est incompatible avec la définition , votre programme a un comportement indéfini.

Pour une fonction qui prend un ou plusieurs arguments, vous pouvez spécifier le type de chaque argument dans la déclaration:

 int bar(int x, double y); 

Les fonctions sans arguments sont un cas particulier. Logiquement, les parenthèses vides auraient été un bon moyen de spécifier qu’un argument, mais que la syntaxe était déjà utilisée pour les déclarations de fonctions de style ancien. Le comité ANSI C a donc inventé une nouvelle syntaxe à l’aide du mot clé void :

 int foo(void); /* foo takes no arguments */ 

Une définition de fonction (qui inclut le code de la fonction) fournit également une déclaration . Dans votre cas, vous avez quelque chose de similaire à:

 int testlib() { /* code that implements testlib */ } 

Ceci fournit une déclaration non-prototype pour testlib . En tant que définition, ceci indique au compilateur que testlib n’a pas de parameters, mais en tant que déclaration, il indique uniquement au compilateur que testlib prend un nombre et un type d’arguments non spécifiés mais fixes.

Si vous modifiez () en (void) la déclaration devient un prototype.

L’avantage d’un prototype est que si vous appelez accidentellement testlib avec un ou plusieurs arguments, le compilateur diagnostiquera l’erreur.

(C ++ a des règles légèrement différentes. C ++ n’a pas de déclarations de fonctions de style ancien et les parenthèses vides signifient spécifiquement qu’une fonction ne prend aucun argument. C ++ supporte la syntaxe (void) pour la cohérence avec C. comstackr à la fois en C et en C ++, vous devriez probablement utiliser le () en C ++ et la syntaxe (void) en C.)

Essayer:

 extern int testlib(void);