¿Por qué convertir un valor de parámetro de función no utilizado en void?

98

En algún proyecto de C, he visto 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;
}

¿Los dos yesos para anular sirven para algo?

bastibe
fuente
Votar para cerrar, ya que la respuesta correcta (inhibiendo las advertencias del compilador sobre parámetros no utilizados) está en la pregunta vinculada de Charles.
TED
@Cody Gray - Fue cerrado por esa razón. Sin embargo, en realidad no era una duplicidad de esa pregunta. 689677 se refería a los retornos de casting al vacío, no a los parámetros.
TED
19
En realidad, ambos duplicados no son válidos para esta pregunta. Uno es C ++, el otro está relacionado con los valores de retorno. No son las mismas cosas . ¿Hay algún parámetro C duplicado?
Matt Joiner
2
Esta es una pregunta diferente a la que cubrían los duplicados sugeridos. Sin embargo, puedo ver por qué se cometió el error. Reabierto (obviamente).
Tim Post
4
Aviso: no cierre esto como un duplicado de una pregunta de C ++, ya que C ++ utiliza (void)con un efecto algo diferente. Esta pregunta es sobre C
Antti Haapala

Respuestas:

89

Está ahí para evitar advertencias del compilador porque algunos parámetros no se utilizan.

Benoit Thiery
fuente
3
¿Cuál es la mejor manera de suprimir las advertencias ?: stackoverflow.com/questions/3417837/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@Benoit, ¿qué es lo que realmente hace casting to void? ¿Su única función es mostrarle al compilador que está ignorando intencionalmente algo o que realmente hace algo (anulado) y cuando el compilador lo ve, lo contará como si hubiera hecho algo con la variable y, por lo tanto, no emitirá una advertencia?
Tan Wang
2
@TanWang Su única función es mostrarle al compilador que está ignorando algo intencionalmente. No hará nada en tiempo de ejecución.
zwol
14

El motivo de tener parámetros no utilizados en el prototipo suele ser porque la función debe ajustarse a alguna API externa; tal vez sea una función de biblioteca, o un puntero a esa función se pasa a otra función que espera esta convención de llamada. Sin embargo, no todos los argumentos utilizados por la convención de llamada son realmente necesarios en la función en sí.

La razón para mencionar el nombre del parámetro en el cuerpo es para evitar advertencias 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) {
                      ^~

Esta advertencia se puede suprimir utilizando el parámetro real en el cuerpo de la función. Por ejemplo, si tiene la siguiente declaración:

ud;

Esta advertencia ahora está suprimida. Sin embargo, ahora GCC producirá otra advertencia:

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

Esta advertencia dice que la declaración ud;, aunque es sintácticamente válida C, no afecta nada en absoluto, y posiblemente sea un error, no muy diferente de la declaración

abort;

que quizás debería haber sido escrito como en abort();cambio para que hiciera algo.

Y ahí es donde (void)entra el elenco: le dirá al compilador de manera inequívoca y explícita que se supone que la declaración no tiene ningún efecto en absoluto.

Antti Haapala
fuente