pepein
pepein

Reputation: 39

What is wrong with this C cast

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[sizeof(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?

Upvotes: 3

Views: 384

Answers (4)

Oren Shemesh
Oren Shemesh

Reputation: 1578

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).

Upvotes: 0

Matt McClellan
Matt McClellan

Reputation: 1669

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 */
}

Upvotes: 10

Tim Schaeffer
Tim Schaeffer

Reputation: 2636

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.

Upvotes: 0

Michael Burr
Michael Burr

Reputation: 340516

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.

Upvotes: 7

Related Questions