8

In the following:

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

I get the output as:

Example(null)
Segmentation Fault

When I tried backtrace in GDB it shows printf() is converted to puts(). But I can't seem to understand why this happens.

BTW I found this article but still can't seem to make sense.

noMAD
  • 7,744
  • 19
  • 56
  • 94
  • `gcc` does various such optimizations. See section 2.3 and 3.1 in particular of http://www.ciselant.de/projects/gcc_printf/gcc_printf.html – FatalError Apr 10 '12 at 21:17
  • 1
    Also see this `gcc` bug report for more discussion on why this isn't considered a bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25609 – shf301 Apr 10 '12 at 21:19
  • A similar question: [Not getting segmentation fault in C](http://stackoverflow.com/questions/8861833/not-getting-segmentation-fault-in-c) – Bo Persson Apr 10 '12 at 21:50
  • @shf301: I found this later version of the bug: http://sources.redhat.com/bugzilla/show_bug.cgi?id=10818 – noMAD Apr 10 '12 at 21:54

1 Answers1

15

The standard says that passing a NULL pointer as argument to a printf with %s specifier is undefined behavior1 (i.e. anything can happen), so both behaviors are licit.

In the first case, the standard library (in particular, the printf code) is doing you a favor by printing (null).

In the second case, instead, the optimizer understands that your printf can be replaced by a puts (which is more efficient) without any change to the "observable behavior" of the program, and so it replaces it. But, puts does not happen to contain the NULL-checking code of the printf, and thus you get a segmentation fault.


  1. C99, §7.19.6.1, ¶8:

    the argument shall be a pointer to the initial element of an array of character type.

    ¶9:

    If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

    You fall in this last case, because NULL is not "a pointer to the initial element of an array of character type.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    Exactly; the second `printf` just prints the given argument followed by a newline, which is exactly what `puts` does; the first one, instead, do somewhat more complicated stuff. Anyhow, these are implementation-specific details: the important thing is that you must not pass `NULL` as argument for a `printf` with `%s`, because it's undefined behavior. – Matteo Italia Apr 10 '12 at 21:22