
take that, web!

take that, web!
most gnome hackers are probably accustomed to the fact that they can pass a null pointer as a value to glibc’s “%s” conversion character and get the string “(null)” output instead of a crash.
take for example, this program:
#include <stdio.h>
int
main (void)
{
printf ("%s", NULL);
return 0;
}
this will output “(null)”. nice. i like this glibc feature.
of course, this program fails to put a newline. let’s make the obvious fix:
#include <stdio.h>
int
main (void)
{
printf ("%s\n", NULL);
return 0;
}
this program segfaults.
why is this?
let’s look at the assembly code generated for the second program:
...
...
main:
....
....
call puts
....
it turns out that if gcc sees “printf (“%s\n”, string);” then it assumes that this is exactly equivalent to “puts (string);” and emits the puts code instead. this is without any optimisation enabled. of course, compiling with -ffreestanding causes it to not make this assumption.
of course, puts will crash if you give it a null pointer.
i guess the assumption is probably valid by strict reading of the relevant specifications (printfing a null string is probably said to be “undefined”) but clearly this feature of gcc is in conflict with the “(null)” feature of glibc.