Format string identifiers have specific purposes. The %d
identifier is for integer values, like short
, int
etc. long
has %ld
more variants as such.
You have a pointer, that holds an address. Although it is a numerical value, it's special in its purpose and should be formatted as %p
, the proper way to print pointers.
Also, the size of pointers may change by architecture, so it may not be the same size as the %d
identifier expects.
Regarding the different values that were printed to the screen: If you were to print the address of a variable in these two formats in the same execution, you may get again one 'positive' hex value and one 'negative' integer value. But, these values are actually the same. Almost.
The integer value representation of the variable is only the lower 32 bits of the 64 bit value, and it's negative because it is signed, and as a pointer representation (since it's an address and sign doesn't matter) it is unsigned hex value and looks positive, though both are the same value in memory (At least the 32 bits that are equal). This is happening because of different width of variable and something called "Two's complement". You can further read about it here
Note: The two values you mentioned are not the same, since you got them in different executions of the program and ASLR was on, the actual address value of a
has changed between executions.
It is important to mention, even though I refer to pointers in this answer as numerical values, it is not correct to regard them as so, as they hold addresses which are their own type category (Thanks @JohnBullinger for clarifying).
Use the correct format identifier to avoid this warning, at it is informing you that you may have miss typed or used the wrong variable since it is not a regular numerical value you're trying to print, but an address.