Thread: casting int and float pointers

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    2

    casting int and float pointers

    I'm just learning, and I've been playing with a copy of the GNU C Tutorial for fun. One of the questions asks "Write a statement which converts a pointer to an integer into a pointer to a double type." I think what the question is getting at is something like "my_double_ptr = (double *) my_int_ptr;".

    But printing the values with printf didn't give me what I expected. So I tried to do something simpler first, and this is what I wrote just to see what would happen:

    Code:
    int main () 
    {
      float my_float = 12.3456;
      float *my_float_ptr;
      int *my_int_ptr;
    
      my_float_ptr = &my_float;
      my_int_ptr = (int *) my_float_ptr;
      printf("My_float_ptr is %p\n", my_float_ptr);
      printf("My_int_ptr is %p\n", my_int_ptr);
      /* printf("My_float_ptr points to float %f\n", *my_float_ptr);
      printf("My_float_ptr points to int %d\n", *my_float_ptr); */
      printf("My_int_ptr points to float %f\n", *my_int_ptr);
      printf("My_int_ptr points to int %d\n", *my_int_ptr);
    
      return 0;
    }
    When I run it with commented lines included, I get the output:
    My_float_ptr is 0x22efc4
    My_int_ptr is 0x22efc4
    My_float_ptr points to float 12.345600
    My_float_ptr points to int -2147483648
    My_int_ptr points to float 12.345598
    My_int_ptr points to int 1095075732

    But when I run it as shown, with comments commented, what I get is:
    My_float_ptr is 0x22efc4
    My_int_ptr is 0x22efc4
    My_int_ptr points to float 0.000000
    My_int_ptr points to int 1095075732

    I can understand if ints and floats are represented differently in storage, then 12.3456 may print out as some screwy int. But what confuses me is why it outputs "My_int_ptr points to float 0.000000" in one case and "My_int_ptr points to float 12.345598" in the other, when all I did was remove a few printf lines.

    Does anyone have any insight into this, or can anyone direct me to some documentation on the web where this might be explained?

    Also, gcc -dumpmachine gives me "i686-pc-cygwin" and gcc -dumpversion gives me "3.3.3".

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Ah, undefined behavior -- it's just so hard to define it.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    May 2005
    Posts
    2
    Let me check to make sure I get it:
    Since there's a float stored at my_int_ptr, *my_int_ptr is not guaranteed to make any sense. So really of the numbers, the only line I can count on displaying in an expected way is printf("My_float_ptr points to float %f\n", *my_float_ptr);.
    Is that the right understanding?

    If so, then I have a follow-up question. As far as floats and ints go, if one can't derefence a pointer of one type when a number of the other type is stored at that address, then would there ever be any practical reason to cast one of these types of pointers to the other? All you'd have after the cast is the address, and no way to tell what's stored there without casting it back to the original type, right?

    The reason I ask is because the original exercise that prompted this asks "Write a statement which converts a pointer to an integer into a pointer to a double type." I'm not sure why anyone would want to do this, other than to complete this exercise...

  4. #4
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Never rely on undefined behavior, as has already been stated. But what is happening is this; when a function takes a variable number of arguments, arguments get default promotions. In particular, any floats (or assumed to be floats) get promoted to doubles. So for example, when you do this:

    printf("My_int_ptr points to float %f\n", *my_int_ptr);

    my_int_ptr gets dereferenced, and the type you gave it is int *, so the value that's pointed to gets treated as an int and pushed onto the stack. However, when printf () goes to recieve the variable number and type of arguments that get passed to it, the only record it has of what you sent is the format specifiers in the format string. It sees %f. However, it knows that no float ever really gets to it; any passed float gets turned into a double before it gets there. In your case, sizeof (float) = sizeof (int) = 4, and sizeof (double) = 8. So in the function call, 4 bytes were pushed onto the stack; now, 8 bytes get taken off. Oops! Now you're in deep water.

    What happens next depends on the calling architecture and implementation specifics that you don't need/want to know as a C programmer, is outside my area of knowledge, and certainly undefined.
    hello, internet!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  2. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  3. Debug Error Really Quick Question
    By GCNDoug in forum C Programming
    Replies: 1
    Last Post: 04-23-2007, 12:05 PM
  4. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM