I want to reinterpret data of one type as another type in a portable way (C99). I am not talking about casting, I want a reinterpretation of some given data. Also, by portable I mean that it does not break C99 rules - I do not mean that the reinterpretated value is equal on all systems.
I know 3 different way to reinterpret data, but only two of these are portable:
This is not portable - it breaks the strict aliasing rule.
/* #1 Type Punning */ float float_value = 3.14; int *int_pointer = (int *)&float_value; int int_value = *int_pointer;
This is platform dependent, because it reads an
int
value from the union after writing afloat
into it. But it does not break any C99 rules, so that should work (ifsizeof(int) == sizeof(float)
)./* #2 Union Punning */ union data { float float_value; int int_value; }; union data data_value; data_value.float_value = 3.14; int int_value = data_value.int_value;
Should be fine, as long as
sizeof(int) == sizeof(float)
/* #3 Copying */ float float_value = 3.14; int int_value = 0; memcpy(&int_value, &float_value, sizeof(int_value));
My Questions:
- Is this correct?
- Do you know other ways to reinterpret data in a portable way?