简体   繁体   中英

What happens when I cast uint8_t array to uint32_t?

Suppose I have this array:

uint8_t arr[10];

located at address 0x00 .

Then I want to assign part of it to uint32_t value. Aggregatin of arr[1], arr[2], arr[3] and arr[4] to 32 bit integer. Here is an example:

uint8_t arr[10];
uint32_t i;
i = *( (uint32_t *)&arr[1] );

What bothers me is that arr[1] is located at address not multiple of four(at address 0x01). So the question is: what would happen on 32bit platform? Is this legal, does it have some disadvantages compared to standard uint32 assignments?

It's illegal, because it breaks strict aliasing rules, resulting in undefined behaviour .

Use memcpy instead:

memcpy(&i, &arr[1], sizeof(i));

But do notice that this code assumes host endianness. If you need endianness independent code, use bit shifting and masking to combine 4 values in to integer, or swap bytes after memcpy (compilers usually offer some kind intrisics for this).

Type punning violates the effective type rules, section 6.5 para 6 and 7 of the C standard. These say that you don't have the right to access an object with a different type than it was declared. (There are some complicated exceptions to these rules, but which don't apply, here.)

Doing so has your program in an undefined state and bad things can happen. As a rule of thumb, never do pointer casts unless you know exactly what you are doing.

If you really need to switch between the byte representation and another type the easiest way is to use a union

union twist {
  unsigned char c[sizeof(uint32_t)];
  uint32_t u;
} val = { .c = { [0] = 7, } };

// now use
val.u

This undefined behavior due to aliasing rules, you can just use an assignment:

i = arr[1];

which converts the uint8_t value to uint32_t value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM