You are taking an int* (which points to lets say 4 bytes) and casting it to a double* (which points to some that is supposed to be more than 4 bytes. This means when you deference your double*, you are reading random data (which might not even be yours) and it will probably be garbage, hence the NaN.
void foo(char* test, int i, double d) {
int* pi = (int*) test;
*pi = i;
pi++;
double* dp = (double*) pi;
*dp = d;
dp++;
}
!!!!
Why not just pass an s* pointer to this function? Why all the typeless casting and raw pointer manipulation.
Ew ew ew.
You'd be lucky if this works at all. The compiler will have to arrange memory in a very specific way in order for this to work (read: it doesn't have to, so this might not always work even if it's working for you now)
EDIT:
After further thought, what's happening in your original code might be what I speculated. The compiler isn't arranging memory like you think it should. It might be putting some bytes of padding between 'i' and 'd' members of the s struct.
It happens to work on float just because the sizes of a float variable and an int variable are the same (4 bytes). If you use GCC, in the "double" case, the size of struct s is 16 bytes (i.e., 2*size(double)), instead of 4+8 bytes. So, after pi++, pi is not pointed to the correct address of the double variable in t.
To play with this code, you can try:
1 2 3 4 5 6 7
void foo(char* test, int i, double d) {
int* pi = (int*) test;
*pi = i;
double* dp = (double*) pi;
dp ++;
*dp = d;
}
However, this coding style is very easy to make mistake. Pass a pointer of struct s is a better choice.
Thanks for your answers guys. I should have clarified that this is a question from a test. So it's bad programming, but it's intentional to camouflage what is really going on. Btw, on some compilers/platforms it prints NaN, on others a random number.
I think Disch may be on the right track:
After further thought, what's happening in your original code might be what I speculated. The compiler isn't arranging memory like you think it should. It might be putting some bytes of padding between 'i' and 'd' members of the s struct.
Does anybody have any more insights into that? Why does it work for the int and when I replace the double with a float? And why can I access the double number in foo() fine, but not in main() anymore?
If you use GCC, in the "double" case, the size of struct s is 16 bytes (i.e., 2*size(double)), instead of 4+8 bytes. So, after pi++, pi is not pointed to the correct address of the double variable in t.
But can you please explain me why the size of the struct is 16 bytes, and not 12?