0

Can someone explain the output of the 2nd line?

int x=10;
printf("%d\n",x);
printf("%p\n",x);
printf("%p\n",&x);

Output:

10
0000000a
006aff0c
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
sabertooth
  • 582
  • 1
  • 7
  • 23
  • https://stackoverflow.com/questions/2369541/where-is-p-useful-with-printf – twain249 Sep 04 '17 at 01:19
  • 5
    Well, it is undefined behavior to use mismatched `printf()` conversion specifiers and arguments; that said, `0000000a` is the hex representation for decimal `10`. – ad absurdum Sep 04 '17 at 01:19
  • Printing integers using `%p` is not guaranteed to work (and, under not uncommon circumstances, such as 64-bit programming, is pretty much guaranteed not to work), but how surprising is it that 10 (base 10) comes out as 0x0a (base 16)? – Steve Summit Sep 04 '17 at 01:21
  • looks like %p always converts anything that went through him into Hexadecimal @DavidBowling – sabertooth Sep 04 '17 at 01:32
  • 1
    @ToufiqueImam-- not exactly; the `%p` conversion specifier prints the value of a pointer [in an implementation-defined way](http://port70.net/~nsz/c/c11/n1570.html#7.21.6.1p8). This may or may not be a hexadecimal representation. Note that pointers must be cast to `(void *)` before printing with `%p` to avoid undefined behavior; e.g., `printf("%p\n",(void *) &x);` – ad absurdum Sep 04 '17 at 01:36
  • Yes, it could technically print out the entire text for Macbeth, as long as the implementation doco said that's what it would do :-) – paxdiablo Sep 04 '17 at 01:48

1 Answers1

7

In your case, it appears to be treating the value 10 as a pointer and outputting it as an eigth-digit, zero-padded-on-the-left, hexadecimal number(a).

However, as per C11 7.21.6.1 The fprintf function, /9 (all standards quotes below also refer to C11):

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

So, literally, anything is permitted to happen. You generally want to avoid undefined behaviour as much as possible, as the behaviour can change between implementations, versions or even the day of the week :-)

There's also technically a problem with your third line. The standard states, in 7.21.6.1 /8 for the p conversion specifier:

The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

Since &x is actually a pointer to int, this puts it in violation of the same contract. You should probably use something like this instead:

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

(a) What it actually does is implementation-defined, as per the second sentence in the final quote above. It can basically do anything, provided the implementation documents it, as specified in J.3 Implementation-defined behavior:

A conforming implementation is required to document its choice of behavior in each of the areas listed in this subclause.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953