C 当我将uint8\u t数组强制转换为uint32\t时会发生什么?

C 当我将uint8\u t数组强制转换为uint32\t时会发生什么?,c,arrays,C,Arrays,假设我有这个数组: uint8_t arr[10]; 位于地址0x00 然后我想把它的一部分赋值给uint32_t值。将arr[1]、arr[2]、arr[3]和arr[4]聚合为32位整数。以下是一个例子: uint8_t arr[10]; uint32_t i; i = *( (uint32_t *)&arr[1] ); 让我烦恼的是,arr[1]位于地址不是四的倍数(地址0x01)。所以问题是:在32位平台上会发生什么?这合法吗?与标准的uint32赋值相比,它是否有一些缺点?

假设我有这个数组:

uint8_t arr[10];
位于地址
0x00

然后我想把它的一部分赋值给uint32_t值。将arr[1]、arr[2]、arr[3]和arr[4]聚合为32位整数。以下是一个例子:

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

让我烦恼的是,
arr[1]
位于地址不是四的倍数(地址0x01)。所以问题是:在32位平台上会发生什么?这合法吗?与标准的
uint32
赋值相比,它是否有一些缺点?

这是非法的,因为它违反了严格的别名规则,导致了错误

改用
memcpy

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

但请注意,此代码假定主机端性。如果您需要与endianness无关的代码,请使用位移位和掩码将4个值合并为整数,或在
memcpy
之后交换字节(编译器通常为此提供某种指令)。

由于别名规则,这种未定义的行为,您可以使用赋值:

i = arr[1];

uint8\u t
值转换为
uint32\u t
值。

类型双关违反了C标准第6.5节第6段和第7段的有效类型规则。这意味着您无权访问与声明的对象类型不同的对象。(这些规则有一些复杂的例外情况,但此处不适用。)

这样做会使您的程序处于未定义状态,并且可能会发生不好的事情。根据经验,除非您确切知道自己在做什么,否则永远不要进行指针投射

如果确实需要在字节表示和其他类型之间切换,最简单的方法是使用联合

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

// now use
val.u

行为不明确;任何事情都可能发生,包括“程序崩溃”和“程序似乎正常工作”。@bolov the failure,thx