Why does printing a null char ('\0', 0) with %s prints the "(null)" string actually?
Like this code:
char null_byte = '\0';
printf("null_byte: %s\n", null_byte);
...printing:
null_byte: (null)
...and it even runs without errors under Valgrind, all I get is the compiler warning warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat]
(note: I'm using gcc 4.6.3 on 32bit Ubuntu)
No, it is not possible to do this without modifying printf(). The null character is only used to signify the end of a string, and should not be printed. More than one call to printf() can contribute to the same 'formatted line'.
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.
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 .
No , printf does not do that in any case .
It's undefined behavior, but it happens that on your implementation:
int
value of 0 that you pass is read by %s
as a null pointer%s
by printf
has special-case code to identify a null pointer and print (null)
.Neither of those is required by the standard. The part that is required[*], is that a char
used in varargs is passed as an int
.
[*] Well, it's required given that on your implementation all values of char
can be represented as int
. If you were on some funny implementation where char
is unsigned and the same width as int
, it would be passed as unsigned int
. I think that funny implementation would conform to the standard.
Well, for starters, you're doing it wrong. '\0'
is a character and should be printed with %c
and not %s
. I don't know if this is intentional for experimentation purposes.
The actual binary value of \0
is, well, 0. You're trying to cast the value 0 to a char *
pointer, which would result in an invalid reference and crash. Your compiler is preventing that with a special treatment of the %s
value.
Valgrind won't catch it because it runs on the resulting binary, not the source code (you'd need a static analyzer instead). Since the compiler has already converted that call into a safe "null pointer" text, valgrind won't see anything amiss.
null_byte contains 0. When you use %s in printf, you are trying to print a string, which is an adress of a char (a char *). What you do in your code, is that you are passing the adress 0 (NULL) as the adress of your string, which is why the output is null. The compiler warned you that you passed the wrong type to the %s modifier. try printf("null_byte: %s\n", &null_byte);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With