How %d works for "" in string ? Result: 4210704

120 views Asked by At
#include <stdio.h>

int main()
{
    printf("%c code\n", 'C');
    printf("%d", "");
    return 0;
}
#include <stdio.h>

int main()
{
    printf("%d", 3); /* result 3 */
    printf("%d", '3'); /* result 51, because 3 is char (from ASCII table) */
    printf("%d", ""); /
    return 0;
}

I'm a beginner at C. I read "C Programming Absolute beginner's Guide" Thurd Edition by Greg Pery and Dean Miller. There are examples of %c %d and %f . I've started experiment with them and noticed thing that i can't explain how it was made. So i tried these examples with %d and understood how first two work. For last one i have ideas how computer read this but I ain't sure how all 0s and 1s combine together. If you have explanation of that, I will glad to response you back)))

4

There are 4 answers

1
John Bode On

How %d works for "" in string ?

Short answer is that it doesn't; %d expects its corresponding argument to be an int, and a string literal is not an int. The behavior is undefined, meaning that neither the compiler nor the runtime environment are required to handle the situation in any particular way. You'll get some kind of output (usually), just don't expect that output to be meaningful in any way.

A string literal like "" is an array expression; its type is "1-element array of char". Under most circumstances, an array expression is converted, or "decays", to a pointer expression and the value of the pointer is the address of the first element of the array. So what you're actually passing to printf is a char * value.

You told printf to expect an int, but you gave it a char *. In practice, most implementations will attempt to interpret that pointer value as an int and format it for display as a decimal integer.

Problem is that on many modern implementations, a pointer value can't be represented in an int so only part of the value is converted and displayed. Some implementations may pass int arguments in specific registers rather than on the stack, so printf may not even be looking in the right place for the value and convert some random bit pattern.

Again, the behavior is undefined so any result is equally "correct".

3
Mureinik On

"" is an empty string, not a character - i.e., it's a pointer with some fancy syntax sugar around it. Since you don't control where this string is allocated, it's allocated to an arbitrary location in the memory, and when using %d to print it, you get the offset from the beginning of the segment that contains it.

Note that on multiple executions of the same program the first two printf statements will always print the same values (3 and 51, as you noted), but the third one may print a different number every time.

1
CherryDT On

"" is a pointer to (i.e. memory address of) a single null byte acting as string terminator for your empty string, somewhere in memory. You see a truncated version of the memory address here. Note the result also won't always be the same, especially when you modify other parts of your program, because that empty string won't always be located at the same address.

5
Vlad from Moscow On

This call

printf("%d", "");

has undefined behavior. From the C Standard (7.21.6.1 The fprintf function):

9 If a conversion specification is invalid, the behavior is undefined.288) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

If you want to output a pointer (in this call of printf the string literal having array type char[1] is implicitly converted to a pointer to its first element of the type char *) as an integer then use header <inttypes.h> and write

#include <inttypes.h>

//...

printf("%" PRIdPTR "\n", ( intptr_t )( void * )"");

Or to output the string literal as a pointer you could write

printf( "%p\n", ( void * )"" );

Here is a demonstration program.

#include <stdio.h>
#include <inttypes.h>

int main( void )
{
    printf( "%08" PRIXPTR "\n", ( uintptr_t )( void * )"" );
    printf( "%p\n", ( void * )"" );
}

Its output might look like

00F19B38
00F19B38

There is used macro PRIXPTR instead of PRIdPTR to output the pointer as an integer in the hexadecimal representation the same way as in case of using the conversion specifier p for pointers.