Pourquoi convertir une valeur de paramètre de fonction inutilisée en void?

98

Dans certains projets C, j'ai vu ce code:

static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
    (void)ud;
    (void)osize;
    /* some code not using `ud` or `osize` */
    return ptr;
}

Les deux lancers pour annuler servent-ils un but?

Bastibe
la source
Voter pour fermer, car la bonne réponse (inhiber les avertissements du compilateur sur les paramètres inutilisés) est dans la question liée de Charles.
TED
@Cody Gray - Il a été fermé pour cette raison. Cependant, ce n'était pas en fait une dupe de cette question. 689677 parlait de la conversion des retours à néant, pas de paramètres.
TED
19
En fait, les deux doublons ne sont pas valables pour cette question. L'un est C ++, l'autre concerne les valeurs de retour. Ce ne sont pas les mêmes choses . Y a-t-il des doublons de paramètres C?
Matt Joiner
2
C'est une question différente de celle couverte par les doublons suggérés. Cependant, je peux voir pourquoi l'erreur a été commise. Rouvert (évidemment).
Tim Post
4
Remarque: veuillez ne pas fermer ceci comme un duplicata d'une question C ++ comme C ++ l'utilise (void)pour un effet quelque peu différent. Cette question concerne C
Antti Haapala

Réponses:

89

Il est là pour éviter les avertissements du compilateur car certains paramètres sont inutilisés.

Benoit Thiery
la source
3
Quelle est la meilleure façon de supprimer les avertissements: stackoverflow.com/questions/3417837/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@Benoit que fait réellement le casting pour annuler? Est-ce que sa seule fonction est de montrer au compilateur que vous ignorez intentionnellement quelque chose ou que (void) fait réellement quelque chose et quand le compilateur le verra, il le comptera simplement comme ayant fait quelque chose avec la variable et donc pas d'avertissement?
Tan Wang
2
@TanWang Sa seule fonction est de montrer au compilateur que vous ignorez intentionnellement quelque chose. Il ne fera rien lors de l'exécution.
zwol du
14

La raison d' avoir des paramètres inutilisés dans le prototype est généralement parce que la fonction doit se conformer à une API externe - peut-être est-ce une fonction de bibliothèque, ou un pointeur vers cette fonction est passé à une autre fonction qui attend cette convention d'appel. Cependant, tous les arguments utilisés par la convention d'appel ne sont pas réellement nécessaires dans la fonction elle-même.

La raison de mentionner le nom du paramètre dans le corps est d'éviter les avertissements tels que

unused.c: In function l_alloc’:
unused.c:3:22: warning: unused parameter ud [-Wunused-parameter]
 void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
                      ^~

Cet avertissement peut être supprimé en utilisant le paramètre réel dans le corps de la fonction. Par exemple, si vous avez l'instruction suivante:

ud;

Cet avertissement est maintenant supprimé. Cependant maintenant GCC produira un autre avertissement:

unused.c:5:5: warning: statement with no effect [-Wunused-value]
     ud;
     ^~

Cet avertissement indique que l'instruction ud;, tout en étant syntaxiquement valide C, n'affecte rien du tout, et est peut-être une erreur, un peu comme l'instruction

abort;

ce qui aurait peut-être dû être écrit abort();pour faire quelque chose.

Et c'est là que la (void)distribution entre en jeu - elle dira au compilateur sans ambiguïté et explicitement que l'instruction est censée n'avoir absolument aucun effet.

Antti Haapala
la source