简体   繁体   English

当我将uint8_t数组转换为uint32_t时会发生什么?

[英]What happens when I cast uint8_t array to uint32_t?

Suppose I have this array: 假设我有这个数组:

uint8_t arr[10];

located at address 0x00 . 位于地址0x00

Then I want to assign part of it to uint32_t value. 然后我想将其中的一部分分配给uint32_t值。 Aggregatin of arr[1], arr[2], arr[3] and arr[4] to 32 bit integer. arr [1],arr [2],arr [3]和arr [4]的聚合为32位整数。 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). 困扰我的是arr[1]位于地址不是四的倍数(地址0x01)。 So the question is: what would happen on 32bit platform? 所以问题是:32位平台会发生什么? Is this legal, does it have some disadvantages compared to standard uint32 assignments? 这是合法的吗,与标准的uint32任务相比,它有一些缺点吗?

It's illegal, because it breaks strict aliasing rules, resulting in undefined behaviour . 这是非法的,因为它违反了严格的别名规则,导致未定义的行为

Use memcpy instead: 请改用memcpy

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). 如果您需要与字节顺序无关的代码,请使用位移和屏蔽将4个值组合成整数,或者在memcpy之后交换字节(编译器通常会为此提供某种内在函数)。

Type punning violates the effective type rules, section 6.5 para 6 and 7 of the C standard. 类型惩罚违反了有效类型规则,即C标准的第6.5节第6和第7节。 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

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. 它将uint8_t值转换为uint32_t值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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