Naor Malca
Naor Malca

Reputation: 143

Why do I get this unexpected output of printf?

I tried to understand how printf works in these cases: (it's a bonus question from a test)

Case 1:

int d=1;
printf("%d",(int)"printf("%d);

The output: 0

Case 2: (with out the %d at the end)

int d=1;
printf("%d",(int)"printf(");

The output: 15554368

How does this work? And why does %d make it different?

Upvotes: 3

Views: 163

Answers (3)

chqrlie
chqrlie

Reputation: 145277

This bonus question is a trick question:

printf("%d",(int)"printf("%d); is parsed as

printf(
       "%d",
       ((int)"printf(") % d
      );

The address of the string "printf(" is converted to int and the modulus operation is computed. Since d = 1, the modulus is always 0. Hence printf outputs 0.

The second call just prints the address of the string converted to int, something that will vary from one environment to another, it may even vary from one run to another (it does on my Mac)...

As a matter of fact, the conversion may even fail and trigger implementation specific behavior. So the answer really should be implementation defined behavior in both cases.

Another question should have been:

int d=1;
printf("%d",(int)printf("%d", d));

Which produces 11. Can you explain why?

Note that even this last question is tricky: calling printf without a proper prototype, for example if <stdio.h> is not included, has undefined behavior.

Upvotes: 4

user2371524
user2371524

Reputation:

Let's start with the second example:

int d=1;
printf("%d",(int)"printf(");

"printf(" here is a string constant, only containing the name of a C function in an attempt to confuse you. A string constant has the type char *, it's a pointer to the first character. The (int) converts the pointer to an integer. While this is implementation defined, you will get some value that is related to the address at which the string "printf(" is actually stored.

So you print a number here that happens to be the result of a pointer converted to int.

Moving on:

int d=1;
printf("%d",(int)"printf(" % d);

There's only one change, and I added spaces to make it obvious: The int you get from your pointer conversion is taken modulo d, so the result is the remainder of the integer division by d. As d is one, there will be never any remainder, any number is divisable by 1 without a remainder. Therefore the result is 0.

Upvotes: 3

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53016

The second %d is not a printf() specifier, it's the % modulo division operator and the int variable d which has a value of 1, what is the difference? they are not alike at all.

The second problem, is that you are casting a pointer to int, which is not well defined.

Upvotes: 2

Related Questions