47 votes

nom de paramètre omis, C ++ vs C

En C ++, j'ai tendance à omettre le nom du paramètre dans certaines circonstances. Mais en C, j'ai eu une erreur quand j'ai omis le nom du paramètre.

Voici le code:

 void foo(int);  //forward-decl, it's OK to omit the parameter's name, in both C++ and C

int main()
{
    foo(0);
    return 0;
}

void foo(int)  //definition in C, it cannot compile with gcc
{
    printf("in foo\n");
}

void foo(int)  //definition in C++, it can compile with g++
{
    cout << "in foo" << endl;
}
 

Pourquoi donc? Ne puis-je pas omettre le nom du paramètre dans la définition de la fonction C?

42voto

adl Points 7294

Non, en C, vous ne pouvez pas omettre les identifiants des paramètres dans les définitions de fonction.

La norme C99 dit:

[6.9.1.5] Si le déclarant comprend une liste de types de paramètres, la déclaration de chaque paramètre doit inclure un identifiant, sauf dans le cas particulier d'une liste de paramètres constituée d'un seul paramètre de type void, auquel cas il ne doit pas y avoir de identifiant. Aucune liste de déclarations ne doit suivre.

21voto

Keith Thompson Points 85120

La raison en est que c'est ce que la langue respective des normes de dire, mais il y a une justification de la différence.

Si vous ne fournissez pas un nom pour un paramètre, alors la fonction ne peut pas se référer à ce paramètre.

En C, si une fonction ignore l'un de ses paramètres, il permet généralement de sens, juste pour le retirer de la déclaration et la définition, et ne pas le transmettre à tous les appels. Une exception peut être une fonction de rappel, où une collection de toutes les fonctions doivent être du même type, mais tous n'ont pas nécessairement l'utilisation de leurs paramètres. Mais ce n'est pas un scénario très commun.

En C++, si la fonction dérivée d'une fonction définie par un parent de la classe, il doit avoir la même signature que le parent, même si l'enfant en fonction de a pas l'usage de l'une des valeurs de paramètre.

(Notez que ce n'est pas lié à des paramètres par défaut; si un paramètre en C++ a une valeur par défaut, l'appelant n'a pas à passer de façon explicite, mais la définition de la fonction a encore à donner un nom si c'est pour se référer à elle.)

7voto

Joseph Quinsey Points 4450

Sur un niveau purement pratique, je dois faire face à ce quotidien. La meilleure solution est d'utiliser le pré-processeur. Mon bon fichier d'en-tête contient:

//-------------------------------------------------------------------------
//  Suppress nuisance compiler warnings. Yes, each compiler can already 
//  do this, each differently! VC9 has its UNREFERENCED_PARAMETER(),
//  which is almost the same as the SUPPRESS_UNUSED_WARNING() below.
//
//  We append _UNUSED to the variable name, because the dumb gcc compiler
//  doesn't bother to tell you if you erroneously _use_ something flagged
//  with __attribute__((unused)). So we are forced to *mangle* the name.
//-------------------------------------------------------------------------
#if defined(__cplusplus)
#define UNUSED(x)       // = nothing
#elif defined(__GNUC__)
#define UNUSED(x)       x##_UNUSED __attribute__((unused))
#else
#define UNUSED(x)       x##_UNUSED
#endif

Un exemple de l'utilisation de INUTILISÉE est:

void foo(int UNUSED(bar)) {}

Parfois, vous avez réellement besoin de faire référence au paramètre, par exemple dans un assert() ou de débogage déclaration. Vous pouvez le faire via:

#define USED_UNUSED(x)  x##_UNUSED // for assert(), debug, etc

Aussi, les éléments suivants sont utiles:

#define UNUSED_FUNCTION(x) inline static x##_UNUSED // "inline" for GCC warning
#define SUPPRESS_UNUSED_WARNING(x) (void)(x) // cf. MSVC UNREFERENCED_PARAMETER

Exemples:

UNUSED_FUNCTION(int myFunction)(int myArg) { ...etc... }

et:

void foo(int bar) {
#ifdef XXX
   // ... (some code using bar)
#else
   SUPPRESS_UNUSED_WARNING(bar);
#endif
}

3voto

Rabbit Points 395

Vous pouvez omettre le nom du paramètre dans la fonction de prototype, mais vous devez le déclarer dans la fonction de mise en œuvre. Par exemple, cette compile et fonctionne très bien sous GCC 4.6.1

void foo(int, int);

void foo(int value, int secondValue)
{
    printf("In foo with value %d and %d!\n", value, secondValue);
}

int main(int argc, char **argv)
{
    foo(10, 15);
    return 0;
}

Sorties: In foo with value 10 and 15!

Pourquoi (autres que parce que les normes de le dire): C++ vous permet d'appeler une fonction sans utiliser tous les arguments, tandis que le C ne l'est pas. Si vous ne fournissez pas tous les arguments d'une fonction en C, le compilateur va jeter error: too few arguments to function 'foo'

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