开发者

What is wrong with this C cast

开发者 https://www.devze.com 2022-12-17 06:11 出处:网络
I came across this in an IRC channel yesterday and didn\'t understand why it was bad behavior: #include <stdio.h>

I came across this in an IRC channel yesterday and didn't understand why it was bad behavior:

#include <stdio.h>

int main(void)
{
     char x[s开发者_C百科izeof(int)] = { '\0' }; int *y = (int *) x;
     printf("%d\n", *y);
}

Is there any loss of data or anything? Can anyone give me any docs to explain further about what it does wrong?


The array x may not be properly aligned in memory for an int. On x86 you won't notice, but on other architectures, such as SPARC, dereferencing y will trigger a bus error (SIGBUS) and crash your program.

This problem may 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 */
}


For one thing, the array x is not guaranteed to be aligned properly for an int.

There's been a conversation topic about how this might affect techniques like placement new. It should be noted that placement new needs to occur on properly aligned memory as well, but placement new is often used with memory that allocated dynamically, and allocation functions (in C and C++) are required to return memory that's suitably aligned for any type specifically so the address can be assigned to a pointer of any type.

The same isn't true for the memory allocated by the compiler for automatic variables.


Why not use a union instead?

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

I haven't verified it, but I would think the alignment problems mentioned by others would not be a problem here. If anyone has an argument for why this isn't portable, I'd like to hear it.


I think that while the alignment issue is true, it is not the whole story. Even if alignment is not a problem, you are still taking 4 bytes on the stack, only one of them initialized to zero, and treating them like an integer. This means that the printed value has 24 un-initialized bits. And using un-initialized values is a basic 'wrong'.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号