2010-11-03 8 views
11

he estado pasando por un código fuente en C y me di cuenta lo siguiente:uso extraño de vacío

void some_func (char *foo, struct bar *baz) 
{ 
    (void)foo; 
    (void)baz; 
} 

¿Por qué se utiliza void aquí? Sé (void) antes de que una expresión indique explícitamente que el valor es desechado; pero ¿alguien puede explicarme los motivos de tal uso?

Respuesta

22

Este código garantiza que no recibirá una advertencia del compilador acerca de que foo y baz no se usen.

+0

Aunque podrían dejarse como recordatorio 'TODO'. – ruslik

+1

Puede no ser un caso de algo que HAY QUE HACER: este podría ser el estado final del código. Por ejemplo, esta función podría ser una devolución de llamada, y esos parámetros realmente no se usan. –

+1

"Asegurar" es un poco demasiado fuerte. Funcionará para algunos compiladores, pero aparentemente no es universal: http://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/ – jamesdlin

8

Lo más probable es que alguien estuviera compilando este código con un compilador que emita advertencias para argumentos no utilizados, y quiso suprimir las advertencias.

6

La razón más probable para que aparezcan esas variables en la función es eliminar las advertencias sobre los argumentos no utilizados.

Sin embargo, dado que es probable que presente aún otra advertencia (ya que probablemente esté utilizando un nivel de advertencia más alto de lo normal), el autor da un paso adicional para eliminarlas también.

En C, la declaración

42; 

es realmente válida, aunque no es muy útil. Si compila:

int main (void) { 
    42; 
    return 0; 
} 

no se quejará (normalmente). Sin embargo, si se compila con gcc -Wall -pedantic que (por ejemplo), que obtendrá algo como:

prog.c: In function `main': 
prog.c:2: warning: statement with no effect 

porque el compilador, con razón, piensa que has vuelto loco.

Poner un molde (void) antes de que algo que genera un valor, como el 42; explícitamente indicará que no le importa el valor.

que he visto este utilizado en algunos compiladores anal retentiva, que insisten en que, debido a una función como printf realidad devuelve un valor, debe estar loco para hacer caso de él, lo que lleva a tales atrocidades como:

(void)printf ("Hello, world.\n"); 
(void)strcpy (dest, src); 

:-)


a modo de ejemplo, si se compila:

void some_func (char *foo) {} 
int main (void) { some_func (0); return 0; } 

con gcc -Wall -W -pedantic, obtendrá:

warning: unused parameter `foo' 

Si "utiliza" el parámetro:

void some_func (char *foo) { foo; } 

obtendrá

warning: statement with no effect 

Sin embargo, si se utiliza el parámetro y ignorar explícitamente el resultado:

void some_func (char *foo) { (void)foo; } 

no recibirás ninguna advertencia.

+0

Soy consciente de este uso (llamando a una función que devuelve algo y pegando un '(nulo)' delante de él para ignorar el valor devuelto); Simplemente tenía curiosidad acerca de por qué uno haría esto para una discusión. – sanjoyd

+0

@theDigtialEngel, mira la actualización. Simplemente mencionar el parámetro en la función reemplaza una advertencia por otra. Tienes que anularlo para eliminar esa segunda advertencia. – paxdiablo

+0

De hecho, puede ir más allá y simplemente dejar caer el nombre del parámetro: 'void some_func (char *) {}' Obtuve esto de http://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler- warnings /, que fue publicado en un comentario de jamesdlin. ¡Conviértalo en la plantilla void ignore (T const &) {} 'y tiene un buen ignorificador de uso general! :) –