Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does printf literally print (null) and what exactly happens?

in a C programming exercise I'm doing something like this (just simplifying):

printf( "%s", 0);

The output is

(null)

What happens here? I assume that printf interprets the zero as a char *, so to NULL? How could I replicate this result by something like

char string[] = NULL; //compiler-error
printf( "%s", string);

?

like image 263
polynomial_donut Avatar asked Jul 21 '15 19:07

polynomial_donut


People also ask

What happens when you print null in C?

The NULL pointer doesn't point to any address, and attempting to print it causes undefined behavior. Undefined meaning it's up to your compiler or C library to decide what to do when it tries to print NULL.

Why null is printed?

It's just the string and the character array parameters that cause ambiguity as character arrays and objects can happily coexist. The char array null cannot be printed by the PrintStream since it causes a NullPointerException .

What is null printing?

A "null printer" is a fake printer that can be used to avoid printing unneeded tickets. This is useful if you need to use the Autocompostage - Auto-check - Auto-control interface, because it needs a ticket.

Why is it printf and not print?

f is for formatted.printf (unlike puts or putchar ) prints formatted output, hence printf. For example it can print an int in hexadecimal, or a float rounded to three decimal places, or a string left padded.


2 Answers

Firstly, your

printf("%s", 0);

leads to undefined behavior (UB). %s in printf requires a char * pointer as argument. You are passing 0, which is an int. That alone already breaks your code, just like

printf("%s", 42); 

would. For that specific UB the fact that 0 is a zero does not make any difference.

Secondly, if you really want to attempt to pass a null-ponter to %s format specifier, you have to do something like

printf("%s", (char *) 0);

Of course, this leads to undefined behavior as well, since %s requires a pointer to a valid string as argument, and (char *) 0 is not a valid string pointer. But some implementations prefer to handle such situations gracefully and just print (null).

In your particular case you just got lucky: printf("%s", 0) "worked" the same way as printf("%s", (char *) 0) would and your implementation saved the day by outputting (null).

like image 167
AnT Avatar answered Oct 22 '22 22:10

AnT


As others have noted, passing a null pointer to printf %s is not guaranteed to do anything. Everything else being equal, we would expect a segmentation violation or other ungraceful crash, as printf attempts to dereference the null pointer. As a convenience, however, many (most?) implementations of printf have, somewhere deep within them, the equivalent of

case 's':
    char *p = va_arg(argp, char *);
    if(p == NULL) p = "(null)";
    fputs(p, stdout);
like image 25
Steve Summit Avatar answered Oct 22 '22 21:10

Steve Summit