Advertencia: ignorando el valor de retorno de ‘scanf’, declarado con el atributo warn_unused_result

#include  int main() { int t; scanf("%d", &t); printf("%d", t); return 0; } 

Compilé el código C anterior usando ideone.com y apareció la siguiente advertencia:

prog.c: En la función ‘principal’:
prog.c: 5: advertencia: ignorando el valor de retorno de ‘scanf’, declarado con el atributo warn_unused_result

¿Puede alguien ayudarme a entender esta advertencia?

El escritor de su libc ha decidido que el valor de retorno de scanf no debe ignorarse en la mayoría de los casos, por lo que le han dado un atributo que le dice al comstackdor que le avise.

Si el valor de retorno no es realmente necesario, entonces está bien. Sin embargo, generalmente es mejor verificarlo para asegurarse de que realmente lea con éxito lo que cree que hizo.

En su caso, el código podría escribirse así para evitar la advertencia (y algunos errores de entrada):

 #include  int main() { int t; if (scanf("%d", &t) == 1) { printf("%d", t); } else { printf("Failed to read integer.\n"); } return 0; } 

La advertencia (con razón) indica que es una mala idea no verificar el valor de retorno de scanf . La función scanf se ha declarado explícitamente (a través de un atributo de función gcc ) para activar esta advertencia si descarta su valor de retorno.

Si realmente quiere olvidarse de este valor de retorno, mientras mantiene contento al comstackdor (y a su conciencia), puede anular el valor de retorno:

 (void)scanf("%d",&t); 

Probé tu ejemplo con gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3. La advertencia se emite si y solo si se optimiza, por ejemplo, con la opción -O2 o -O3. Solicitar todas las advertencias (-Wall) no importa. El lenguaje clásico de casting to void no tiene efecto , no suprime la advertencia.

Puedo silenciar la advertencia escribiendo

 if(scanf("%d",&t)){}; 

esto funciona, pero es un poco oscuro para mi gusto. Vacío {} evita otra advertencia -Wempty-body

Hacer esto:

 int main() { int t; int unused __attribute__((unused)); unused = scanf("%d",&t); printf("%d",t); return 0; } 

Una forma de resolver esto es la función IGUR() como se ve a continuación. Extremadamente feo, pero sin embargo algo portátil. (Para comstackdores antiguos que no entienden en inline simplemente #define inline /*nothing*/ , como de costumbre).

 #include  #include  #include  void inline IGUR() {} /* Ignore GCC Unused Result */ void IGUR(); /* see https://stackoverflow.com/a/16245669/490291 */ int main(int argc, char **argv) { char buf[10*BUFSIZ]; int got, fl, have; fl = fcntl(0, F_GETFL); fcntl(0, F_SETFL, fl|O_NONBLOCK); have = 0; while ((got=read(0, buf, sizeof buf))>0) { IGUR(write(1, buf, got)); have = 1; } fcntl(0, F_SETFL, fl); return have; } 

Por cierto este ejemplo, sin locking, copia de stdin a stdout hasta que se leyó toda la entrada en espera, devolviendo true (0) si no había nada allí, sino false (1). (Previene el retraso de 1s en algo así como while read -t1 away; do :; done en bash .)

Comstack sin aviso bajo -Wall (Debian Jessie).

Edición: IGUR() debe definirse sin inline , de modo que esté disponible para el enlazador. De lo contrario, con cc -O0 podría fallar. Consulte: https://stackoverflow.com/a/16245669/490291

scanf, printf son funciones que devuelven valor, normalmente en ese tipo de funciones es la cantidad de caracteres leídos o escritos. Si se produce un error, puede detectar el error también con el código de retorno. Una buena práctica de progtwigción será mirar el valor de retorno, sin embargo, nunca vi a alguien que mira el valor de retorno de printf …

Si desea que desaparezca la advertencia, probablemente pueda cambiar la gravedad del comstackdor.

Después de leer todas las respuestas y comentarios en esta página, no veo estas otras opciones para evitar la advertencia:

Al comstackr con gcc puede agregar a su línea de comando:

gcc -Wall -Wextra -Wno-unused-result proc.c -o prog.x

Otra opción es usar -O0 como “nivel de optimización cero” ignora la advertencia.

Usar cast to (void) simplemente no sirve para comstackr con gcc

Si depura su código, siempre puede usar assert() como en el siguiente ejemplo:

 u = scanf("%d", &t); assert(u == 1); 

Pero ahora, si desactiva asertar a través de #define NDEBUG obtendrá una -Wunused-but-set-variable . A continuación, puede desactivar esta segunda advertencia de una de estas dos maneras:

  1. Agregando -Wno-unused-but-set-variable a su línea de comando gcc , o
  2. Declarar la variable con atributo: int u __attribute__((unused));

Como se señaló en otra respuesta, la segunda opción desafortunadamente no es muy portátil, aunque parece ser la mejor opción.

Por último, el bramido MACRO definido puede ayudarlo si está seguro de que desea ignorar el retorno de una función determinada, pero no se siente cómodo al desactivar las advertencias para todos los retornos de funciones no utilizados:

 #define igr(x) {__typeof__(x) __attribute__((unused)) d=(x);} double __attribute__ ((warn_unused_result)) fa(void) {return 2.2;} igr(fa()); 

Ver también esta respuesta.

En realidad, depende de lo que necesite, si solo desea deshabilitar la advertencia del comstackdor, simplemente puede ignorar el valor de retorno de la función mediante la conversión forzada o simplemente puede manejarla, el significado de la función scanf es el conteo de entrada del usuario.

==== actualización ====

Puedes usar

(void) scanf("%d",&t);

ignorar el valor de retorno de scanf