Skip to content
Advertisement

Why the address of the pointer variable printed differently between two printf statements without any modification to the variable?

In below simple c test program two printf statements return different values. ( check last four printf statements).

int main ()
{
    char c, *cc;
    int i;
    long l;
    float f;
    c = 'Z';
    i = 15;
    l = 7777;
    f = 9999999312;
    cc = &c;
    printf("nc = %c, cc= %u", *cc, cc);
    cc = &i;
    printf("nc = %d, cc= %u", *cc, cc);
    cc = &l;
    printf("nc = %ld, cc= %u", *( long* )cc, cc);
    printf("nc = %ld, cc= %u", *cc, cc);
    cc = &f;
    printf("nc = %f, cc= %u", *(float *)cc, cc);
    printf("n cc= %u", cc);
    printf("nc = %f, cc= %u", *cc, cc);
    printf("nc = %f, cc= %u", *(float *)cc, cc);

    printf("nc = %f, cc using pointer  = %p", *(float *)cc, cc);
    printf("nc = %f, cc using pointer  =%p", *cc, cc);

    return 0;
}

output : –

c = Z, cc= 755585903
c = 15, cc= 755585904
c = 7777, cc= 755585912
c = 97, cc= 755585912
c = 9999998976.000000, cc= 755585908
cc= 755585908
c = 9999998976.000000, cc= 4294967288
c = 9999998976.000000, cc= 755585908
c = 9999998976.000000, cc using pointer  = 0x7ffc37f4ace4
c = 9999998976.000000, cc using pointer  =0xfffffff8

I am running it in eclipse ide and using Ubuntu Linux.

Why does it behave differently?

Advertisement

Answer

In several places you are using the wrong format specifier to printf. In particular, on this line:

printf("nc = %f, cc= %u", *cc, cc);

The first parameter has type char, but you use %f which expects a double. Also, the second parameter has type char * but %u is expecting an unsigned int. Using the wrong format specifiers invokes undefined behavior.

That being said, here is what is most likely happening under the hood:

On most hosted implementations, floating point numbers are not pushed onto the stack the way integer types and pointers are, but are instead stored in a floating point register.

When you run the above printf command, both *cc and cc are pushed onto the stack because neither of them are floating point numbers. When printf then looks for the first parameter it sees %f, so it retrieves a value from a floating point register. Since you did actually pass a floating point value the prior time you called printf that value is still there, and that value happens to be the value you actually wanted to print, so that’s what gets printed.

Then when printf goes to print the next parameter, it sees %u in the format so the value is pulled from the stack. That value is *cc, which points to the first byte in the representation of f.

Assuming a float is a IEEE754 single precision floating point number, the value it contains is represented as 0xf8021550. The first byte of that is 0xf8. Since cc points to a char, which in your case appears to be signed, it is interpreted as a negative value. When passed to printf the value is promoted to type int, so the actual value passed in is 0xfffffff8, which is what you see being printed.

To reiterate however, the output you’re seeing is undefined behavior. The output could change if you build it on a different machine, use a different compiler, or just use a different optimization setting.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement