176 votes

fonction de déclaration isn ' t un prototype

J'ai une bibliothèque que j'ai créé,

mylib.c:

#include <mylib.h>
int
testlib() {
    printf("Hello world\n");
    return (0);
}

mylib.h:

#include <stdio.h>
extern int testlib();

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

myprogram.c:

#include <mylib.h>

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

Lorsque je tente de compiler ce programme, j'obtiens l'erreur suivante:

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

Je suis l'aide de: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)

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

375voto

Pramod Points 3580

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 de 0 arguments. En C++, ils signifient la même chose. Je vous suggère d'utiliser void systématiquement quand vous voulez dire pas d'arguments.

Si vous avez une variable a, extern int a; est une façon de dire au compilateur qu' a est un symbole qui peut être présente dans une unité de traduction différentes (compilateur C de parler pour le fichier source), ne pas le résoudre jusqu'à ce moment de la liaison. D'autre part, les symboles qui sont les noms de fonction sont de toute façon résolue au moment de la liaison. La signification de classe de stockage de spécificateur sur une fonction (extern, static) seulement une incidence sur la visibilité et l' extern est la valeur par défaut, alors extern est en fait inutile.

Je suggère le retrait de l' extern, il est étrangère et est généralement omis.

56voto

Keith Thompson Points 85120

Réponse rapide: changement int testlib() de int testlib(void) pour indiquer que la fonction ne prend pas d'arguments.

Un prototype est, par définition, une déclaration de fonction qui spécifie le type(s) de la fonction de l'argument(s).

Un non-prototype déclaration de fonction comme

int foo();

est un vieux de la déclaration de style qui ne précise pas le nombre ou le type des arguments. (Avant 1989 en C ANSI standard, c'était le seul genre de déclaration de la fonction dans la langue.) Vous pouvez appeler cette fonction avec un nombre quelconque d'arguments, et le compilateur n'a pas à se plaindre, mais si l'appel 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);

Fonctions sans arguments sont un cas particulier. Logiquement, les parenthèses vides aurait été un bon moyen de spécifier qu'un argument mais que la syntaxe était déjà en usage pour les vieux style déclarations de fonction, de sorte que le C ANSI comité a inventé une nouvelle syntaxe à l'aide de l' void mot-clé:

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

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

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

Cela fournit un non-prototype de déclaration de l' testlib. Comme une définition, elle indique au compilateur qu' testlib n'a pas de paramètres, mais comme une déclaration, il ne indique au compilateur qu' testlib prend un peu quelconque, mais fixe le nombre et le type(s) d'arguments.

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

L'avantage d'un prototype, c'est que si par inadvertance, vous appelez testlib avec un ou plusieurs arguments, le compilateur devra en diagnostiquer l'erreur.

C++ a des règles légèrement différentes. C++ n'a pas de style ancien déclarations de fonction, et des parenthèses vides spécifiquement à dire qu'une fonction ne prend pas d'arguments. C++ prend en charge l' (void) de la syntaxe pour des raisons de cohérence avec C. Mais à moins que vous avez spécifiquement besoin de votre code à compiler à la fois comme le C et le C++, vous devriez probablement utiliser l' () en C++ et l' (void) de syntaxe dans C.)

24voto

Lasse V. Karlsen Points 148037

Essayer:

 extern int testlib(void);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X