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?


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, 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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.