8

I was working with some of the interview questions when I found this code.

#include<stdio.h>
int main()
{
 short int a=5;

 printf("%d"+1,a);    //does not give compiler error 

 return 0;
}

It prints the following:

d

I am unable to understand how the printf function works here.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
user3126632
  • 467
  • 2
  • 8
  • 15

4 Answers4

16

Let's look at the first argument to the printf() call.

"%d" + 1

This points to the same thing as ptr does in the following code.

char *ptr = "%d";
ptr = ptr + 1;

So, what does it mean to increment a pointer? Well, we advance the pointer sizeof(*ptr) * 1 bytes forward.

So, in memory we have:

%d\0
^^
||
|This is where ("%d" + 1) points to.
This is where ("%d") points to.

So, your code is more or less functionally equivalent to doing:

short int a = 5;
printf("d", a);

Which will evaluate and then ignore the extra function argument and print d.


One more thing: You're very close to causing undefined behavior in that code. printf("%d", a) is using the wrong format string. The correct format string for a short int is "%hd".

You can find a full table of format strings here.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • 7
    It's not a problem to print `short`s with `%d`. They're promoted to `int` anyway. – mafso Sep 26 '14 at 17:18
  • what does % operator in printf suggest the compiler to do – user3126632 Sep 26 '14 at 17:24
  • What happens for this printf("%",a); – user3126632 Sep 26 '14 at 17:54
  • @user3126632: it is not a compiler instruction. `printf` is a simple function that scans its first argument, the format string, for sequences it recognizes. Read `man printf`. – Jongware Sep 26 '14 at 21:13
  • 2
    Incrementing a pointer means to move it `1` position forward, not `sizeof(*ptr) * 1`. The latter expression is the number of bytes. – M.M Sep 27 '14 at 02:49
  • @MattMcNabb: I intended that to mean that it moves it forward `sizeof(*ptr) * 1` bytes. Fixing with: `s/positions/bytes`. If you think there's a better way to word it, feel free to edit it in as well. – Bill Lynch Sep 27 '14 at 03:07
7

"%d" + 1 does pointer arithmetic, the compiler sees it as "d", so

printf("%d"+1,a); 

becomes:

printf("d", a); 

You can see why it outputs d in your compiler.

As @sharth points out in the comment, the extra argument a here is evaluated and discarded.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 8
    It's not undefined behavior to pass extra arguments. It's only undefined if you pass too few. http://stackoverflow.com/a/3579752/47453 – Bill Lynch Sep 26 '14 at 16:22
  • @sharth I did not know that. It's so nice to learn something new through answering ;) – Yu Hao Sep 26 '14 at 16:26
2

This is my answer based off @DCoder 's comment. "%d" is a pointer to the first character of the two character array %d. Incrementing this by one gives a pointer to d. The fact that there is a second argument now does not matter as the result of the expression "%d"+1 is simply the character d. If you try adding 0 your output is 5 as expected. If you try adding 2, there is no output as there is only "" is being passed to printf.

Micah Smith
  • 4,203
  • 22
  • 28
1

In this case printf("%d"+1,a); = printf("d",a).

You are specifying printf to print from +1 position which is "d", so printf will simply print d on screen.

ani627
  • 5,578
  • 8
  • 39
  • 45