0

Recently I came across this interview question to determine the output of the following printf statements:

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

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

test (null)

test (null)

Segmentation fault (core dumped)

I am not able to figure out why does it have a segmentation fault in the last 2 printf's and not for the first 2 cases.

user1692342
  • 5,007
  • 11
  • 69
  • 128

3 Answers3

1

The behavior is undefined.
Standard says

C11- 7.21.6/9

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

%s in printf expects an argument that should be a pointer to the initial element of an array of character type.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
0

What is the behavior of printing NULL with printf's %s specifier?

Have a look at the above link,i hope it helps!

Community
  • 1
  • 1
Steve
  • 58
  • 9
0

This is an interview question? The only valid answer is "it will paint your cat green, or maybe do something completely different like travelling to the end of the universe". If they don't accept this as an answer, you don't want to work there.

To be a little more serious here, the output you see is probably created with the GNU C library?

Passing 0 for a %s conversion is undefined behavior and the most probable result of it is a crashing program. glibc has some safety measures built in that replace the string (null) automatically for 0 pointers. You could argue whether this is a great idea, but it's legal because the behavior is undefined -- an implementation can do whatever it wants. Including a crash like you experience it later.

  • The linked SO question is an interesting answer, perhaps the interviewer wanted more than just "it's UB", when in the first case, it's plainly implementation defined. – Weather Vane Oct 31 '15 at 19:32
  • 3
    @WeatherVane but it isn't *implementation defined*, it's *undefined*. *implementation defined* would mean that the standard requires an implementation to define it. It doesn't. `glibc`'s `printf()` is still free to define it, of course. –  Oct 31 '15 at 19:33
  • That's just semantics: you woudn't get the job! How could it print the text "(null)" if it was undefined? – Weather Vane Oct 31 '15 at 19:34
  • I wouldn't **want** this job if they want to hear *implementation defined* ;) –  Oct 31 '15 at 19:34
  • 1
    @WeatherVane regarding your edit: **because** it's undefined. *"ub"* means an implementation can do whatever it wants and doesn't even have to document it (but it can, of course). The difference to *implementation defined behavior* is that an implementation *has* to document what will happen. –  Oct 31 '15 at 19:38
  • 1
    So perhaps that's the sort of discussion the interviewer is trying to draw you into, interview questions often have *undefined answers*! – Weather Vane Oct 31 '15 at 19:41
  • @WeatherVane if **that**'s the reason for this question, and they are looking for somebody with **rock solid** standard C knowledge -- fine for me :) I kind of doubt it, but it doesn't matter much here :) –  Oct 31 '15 at 19:43
  • @WeatherVane; Agreed that some of interview questions often have undefined answer but in this particular case the answer is defined; program's behavior is undefined as per C standard. Implementation defined and undefined behavior are two different things. – haccks Oct 31 '15 at 20:02
  • @haccks yes I realise that "implementation defined" is a particular phrase belonging to the standard, and in this case it is "undefined behaviour" that was however "defined by the implementation", which caught the first pair of cases, but not the second, because the compiler used `puts()`, and so the implementation of what the standard says is undefined behaviour, was a poor effort by the compiler writer, being inconsistent. – Weather Vane Oct 31 '15 at 20:14
  • 2
    @WeatherVane well it doesn't matter much, because it's undefined. The call to `puts()` is done by the optimizer and defeats `glibc`'s attempt to do something "safe" when `0` is passed for `%s`. Still this attempt conforms to the C standard :) But I'd argue, too ... just let the thing crash and don't care for *"ub"* usage. (if client code can't adhere to the contract of the function, a crash is well deserved and even follows the *fail early* principle :)) –  Oct 31 '15 at 20:24