2012-04-10 18 views
8

En el siguiente:Dos casos al intentar imprimir NULL, se trabaja, otros segfaults

printf("Example%s\n",NULL); 
printf("%s\n",NULL); 

Me da la salida como:

Example(null) 
Segmentation Fault 

Cuando traté traza en GDB se muestra printf() es convertido a puts(). Pero no puedo entender por qué sucede esto.

BTW He encontrado this artículo pero todavía no parece tener sentido.

+0

' gcc' realiza varias funciones, tales optimizaciones. Véase la sección 2.3 y 3.1 en particular de http://www.ciselant.de/projects/gcc_printf/gcc_printf.html – FatalError

+1

Consulte también este informe de error 'gcc' para obtener más información sobre por qué esto no se considera un error: http: //gcc.gnu. org/bugzilla/show_bug.cgi? id = 25609 – shf301

+0

Una pregunta similar: [No obteniendo un error de segmentación en C] (http://stackoverflow.com/questions/8861833/not-getting-segmentation-fault-in-c) –

Respuesta

15

La norma dice que la aprobación de un puntero NULL como argumento a una printf con %s especificador es un comportamiento indefinido (es decir, cualquier cosa puede suceder), por lo que ambos comportamientos son lícitas.

En el primer caso, la biblioteca estándar (en particular, el código printf) te está haciendo un favor al imprimir (null).

En el segundo caso, el optimizador entiende que su printf puede reemplazarse por un puts (que es más eficiente) sin ningún cambio en el "comportamiento observable" del programa, por lo que lo reemplaza. Pero, puts no contiene el código de comprobación NULL del printf, y por lo tanto se obtiene un error de segmentación.


  1. C99, §7.19.6.1, ¶8:

    el argumento será un puntero al primer elemento de un array de tipo carácter.

    ¶9:

    Si algún argumento no es del tipo correcto para la especificación de conversión correspondiente, el comportamiento es indefinido.

    Tumbes y en este último caso, debido a NULL no es "un puntero al primer elemento de un array de tipo carácter.

+1

Exactamente; el segundo 'printf' simplemente imprime el argumento dado seguido por una nueva línea, que es exactamente lo que' puts' hace; el primero, en cambio, hacer algo un poco más complicado. De todos modos, estos son detalles específicos de la implementación: lo importante es que no debes pasar 'NULL' como argumento para' printf' con '% s', porque es un comportamiento indefinido. –

+0

Gracias por su ayuda :) – noMAD

Cuestiones relacionadas