Por que lançar valores de retorno não utilizados para anular?

int fn(); void whatever() { (void) fn(); } 

Existe alguma razão para rejeitar um valor de retorno não utilizado, ou estou certo em pensar que é uma completa perda de tempo?

Acompanhamento:

Bem, isso parece bastante abrangente. Suponho que seja melhor do que comentar um valor de retorno não utilizado, pois o código de auto-documentação é melhor que os comentários. Pessoalmente, eu vou desligar esses avisos já que é um ruído desnecessário.

Eu vou comer minhas palavras se um bug escapa por causa disso …

A resposta de David praticamente cobre a motivação para isso, para mostrar explicitamente outros “desenvolvedores” que você sabe que esta function retorna, mas você está explicitamente a ignorando.

Esta é uma maneira de garantir que, sempre que necessário, os códigos de erro sejam sempre manipulados.

Eu acho que para C ++ este é provavelmente o único lugar que eu prefiro usar o estilo C também, já que usar a notação de casting completamente estática parece um exagero aqui. Finalmente, se você está revisando um padrão de codificação ou escrevendo um, então também é uma boa idéia declarar explicitamente que as chamadas para operadores sobrecarregados (não usando a notação de chamada de function) devem ser isentas disso também:

 class A {}; A operator+(A const &, A const &); int main () { A a; a + a; // Not a problem (void)operator+(a,a); // Using function call notation - so add the cast. 

No trabalho, usamos isso para reconhecer que a function tem um valor de retorno, mas o desenvolvedor afirmou que é seguro ignorá-lo. Desde que você marcou a pergunta como C ++, você deve estar usando static_cast :

 static_cast(fn()); 

No que diz respeito ao compilador, lançar o valor de retorno para vazio tem pouco significado.

A verdadeira razão para fazer isso remonta a uma ferramenta usada no código C, chamada lint .

Analisa código procurando possíveis problemas e emitindo avisos e sugestões. Se uma function retornasse um valor que não fosse verificado, o lint avisaria caso isso fosse acidental. Para silenciar esse aviso, você lança a chamada para (void) .

A conversão para void é usada para suprimir avisos do compilador para variables ​​não usadas e valores ou expressões de retorno não salvos.

The Standard (2003) diz em §5.2.9 / 4 diz,

Qualquer expressão pode ser convertida explicitamente para o tipo “cv void”. O valor da expressão é descartado .

Então você pode escrever:

 //suppressing unused variable warnings static_cast(unusedVar); static_cast(unusedVar); static_cast(unusedVar); //suppressing return value warnings static_cast(fn()); static_cast(fn()); static_cast(fn()); //suppressing unsaved expressions static_cast(a + b * 10); static_cast( x &&y || z); static_cast( m | n + fn()); 

Todos os formulários são válidos. Eu costumo torná-lo mais curto como:

 //suppressing expressions (void)(unusedVar); (void)(fn()); (void)(x &&y || z); 

Também está bem.

Para a funcionalidade do seu programa de transmissão para anular é sem sentido. Eu também argumentaria que você não deveria usá-lo para sinalizar algo para a pessoa que está lendo o código, como sugerido na resposta de David. Se você quiser comunicar algo sobre suas intenções, é melhor usar um comentário. Adicionando um casting como este só vai parecer estranho e levantar questões sobre o possível motivo. Apenas minha opinião…

Em C, é perfeitamente correto anular. Praticamente qualquer um entenderá a intenção da declaração.

Em C ++, você tem outras ferramentas à sua disposição. Como os castings em C geralmente são desaprovados, e como o casting explícito para anular provavelmente surpreenderá seus colegas de trabalho (isso me surpreende), eu tenho esse modelo de function em algum lugar

 template  void use_expression(const T&) {} 

e eu uso

 ... use_expression(foo()); 

onde eu escreveria (void)foo() em C.

O vazamento é nulo. É apenas uma informação para o compilador como tratá-lo.

Além disso, ao verificar se seu código está em conformidade com os padrões MISTA (ou outros), ferramentas automáticas como LDRA não permitirão que você chame uma function que tenha um tipo de retorno sem retorná-lo, a menos que você converta explicitamente o valor retornado para (void)