#include<stdio.h>
int main(){
int a = 3;
printf("%u\n",&a);
printf("%d\n",&a);
return 0;
}
I was trying to print address of Variable, "a". Now with usage of two different format specifier, "%u" and "%d", two different memory address is printed which I find it wierd.
So My Question is what difference between two format specifier?
CodePudding user response:
Using the both conversion specifiers to output an address invokes undefined behavior.
From the C Standard (7.21.6.1 The fprintf function)
9 If a conversion specification is invalid, the behavior is undefined.275) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
Instead you should use the conversion specifier p
as for example
printf( "%p\n", ( void * )&a );
Another approach is to use integer types intptr_t
or uintptr_t
declared in the header <stdint.h>
and to use specifiers PRIdPTR
or PRIuPTR
or, for example, PRIxPTR
declared in the header <inttypes.h>
to output assigned values of pointers of the type void *
.
Here is a demonstration program.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main( void )
{
int a = 3;
intptr_t p1 = ( intptr_t )( void * )&a;
uintptr_t p2 = ( uintptr_t )( void * )&a;
printf( "&a = %p\n", ( void * )&a );
printf( "&a = %"PRIdPTR "\n", p1 );
printf( "&a = %"PRIuPTR "\n", p2 );
printf( "&a = %#"PRIxPTR "\n", p2 );
}
The program output is
&a = 0x7ffc220b16ec
&a = 140720879638252
&a = 140720879638252
&a = 0x7ffc220b16ec
CodePudding user response:
%d
is for signed integers, %u
is for unsigned integers.
So, when you print the same value out with %d
and with %u
, you may get different values, since the bytes you're printing out are being interpreted differently. (Once as a signed integer, once as an unsigned integer.)
Final note, you should use %p
("p" for "pointer") to print out addresses.
CodePudding user response:
Well of course "%u\n"
has different address than "%d\n"
because these are different values created one after another. Look at ASM:
RDX
register will have the same value for both printf
calls because of LEA instruction is putting the same address into it.
But what you probably see are the values of RCX
register which contains different printf
format value address for each printf
call.
Now the answer:
%d
is signed decimal integer.
%u
is unsigned decimal integer.
The problem occurs when there is a printf
call. This function changes the value of RDX register which is the memory address of a
variable.