What is wrong with this casting C

Yesterday I met this on the IRC channel and did not understand why this was a bad behavior:

#include <stdio.h> int main(void) { char x[sizeof(int)] = { '\0' }; int *y = (int *) x; printf("%d\n", *y); } 

Is there data loss or something else? Can someone give me any documents to further explain what he is doing wrong?

+4
source share
4 answers

Array x may not be aligned correctly in memory for int . On x86 you will not notice, but on other architectures such as SPARC, dereferencing y will result in a bus error (SIGBUS) and will crash your program.

This problem can occur for any address:

 int main(void) { short a = 1; char b = 2; /* y not aligned */ int* y = (int *)(&b); printf("%d\n", *y); /* SIGBUS */ } 
+10
source

On the one hand, the x array cannot be correctly aligned for int .

There was a conversation about how this might affect methods such as placing new . It should be noted that new placements should also arise in correctly combined memory, but the placement of new ones is often used with dynamically allocated memory, and the distribution functions (in C and C ++) are necessary to return a memory suitable for any type, so the address can be assigned to a pointer of any type.

The same does not apply to memory allocated by the compiler for automatic variables.

+7
source

Why not use union instead?

 union xy { int y; char x[sizeof(int)]; }; union xy xyvar = { .x = { 0 } }; ... printf("%d\n", xyvar.y); 

I have not tested it, but I think that the alignment problems mentioned by others will not be a problem here. If someone has an argument in favor of why this is not tolerated, I would like to hear it.

0
source

I think that although the alignment problem is correct, this is not the whole story. Even if alignment is not a problem, you still take 4 bytes on the stack, only one of them is initialized to zero and processes them as a whole. This means that the printed value has 24 unused bits. And the use of uninitialized values ​​is the main β€œwrong."

(Assume sizeof (int) == 4 for simplicity).

0
source

All Articles