cpointersprintfundefined-behaviorconversion-specifier

Format Specifier: %u vs %d in C


#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?


Solution

  • 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