Por que converter um valor de parâmetro de função não utilizado para void?

98

Em alguns projetos C, vi este código:

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;
}

Os dois elencos a serem anulados servem a algum propósito?

bastibe
fonte
Votando para fechar, pois a resposta correta (inibindo avisos do compilador sobre parâmetros não utilizados) está na pergunta vinculada de Charles.
TED de
@Cody Gray - Foi fechado por esse motivo. No entanto, não foi de fato um truque dessa questão. 689677 estava falando sobre fundir retorna ao vazio, não parâmetros.
TED de
19
Na verdade, ambas as duplicatas não são válidas para esta pergunta. Um é C ++, o outro é referente aos valores de retorno. Estas não são as mesmas coisas . Existe alguma duplicata de parâmetro C?
Matt Joiner
2
Esta é uma questão diferente da abrangida pelas duplicatas sugeridas. Posso ver por que o erro foi cometido, no entanto. Reaberto (obviamente).
Tim Post
4
Aviso: por favor, não feche isso como uma duplicata de uma questão C ++, pois C ++ usa (void)para um efeito um pouco diferente. Esta pergunta é sobre C
Antti Haapala

Respostas:

89

Ele existe para evitar avisos do compilador porque alguns parâmetros não são usados.

Benoit Thiery
fonte
3
Qual é a melhor maneira de suprimir os avisos: stackoverflow.com/questions/3417837/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@Benoit, o que o casting to void realmente faz? É sua única função mostrar ao compilador que você está intencionalmente ignorando algo ou (void) realmente faz algo e quando o compilador vê isso, ele apenas contará como tendo feito algo com a variável e, portanto, não emitirá um aviso?
Tan Wang,
2
@TanWang Sua única função é mostrar ao compilador que você está ignorando algo intencionalmente. Não fará nada em tempo de execução.
zwol
14

A razão para ter parâmetros não usados no protótipo é geralmente porque a função precisa estar em conformidade com alguma API externa - talvez seja uma função de biblioteca ou um ponteiro para essa função é passado para outra função que espera essa convenção de chamada. No entanto, nem todos os argumentos usados ​​pela convenção de chamada são realmente necessários na própria função.

A razão para mencionar o nome do parâmetro no corpo é para evitar avisos como

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) {
                      ^~

Este aviso pode ser suprimido usando o parâmetro real no corpo da função. Por exemplo, se você tiver a seguinte declaração:

ud;

Este aviso foi suprimido. No entanto, agora o GCC produzirá outro aviso:

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

Este aviso informa que a instrução ud;, embora seja sintaticamente válida em C, não afeta absolutamente nada e é possivelmente um erro, não muito diferente da instrução

abort;

que talvez devesse ter sido escrito abort();para fazer algo.

E é aí que (void)entra o elenco - ele dirá ao compilador sem ambigüidade e explicitamente que a instrução não deve ter absolutamente nenhum efeito.

Antti Haapala
fonte