繁体   English   中英

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

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

假设我有这个数组:

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

但请注意,此代码假定主机字节序。 如果您需要与字节顺序无关的代码,请使用位移和屏蔽将4个值组合成整数,或者在memcpy之后交换字节(编译器通常会为此提供某种内在函数)。

类型惩罚违反了有效类型规则,即C标准的第6.5节第6和第7节。 这些表示您无权访问具有与声明的类型不同的对象。 (这些规则有一些复杂的例外,但这里不适用。)

这样做会使您的程序处于未定义状态,并且可能会发生错误。 根据经验,除非你确切知道自己在做什么,否则永远不要做指针演员。

如果你真的需要在字节表示和另一种类型之间切换,最简单的方法是使用union

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

// now use
val.u

由于别名规则导致的这种未定义的行为,您只需使用一个赋值:

i = arr[1];

它将uint8_t值转换为uint32_t值。

暂无
暂无

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

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