gpt4 book ai didi

在 8 位平台或 32 位平台上将 uint8_t 的元素转换为 32 位变量

转载 作者:太空宇宙 更新时间:2023-11-04 06:13:41 27 4
gpt4 key购买 nike

让我们考虑两个例子

1:8 位 MCU/MPU/平台 - 小端

uint8_t arr[5] = {0x1,0x2,0x3,0x4,0x5};//assume &arr[0] == 0x0
uint32_t *ui32 = (uint32_t*)&arr[1];

*ui32 的值是多少? 0x2030405?在这个平台上是否有必要将 uint32_t 变量放置到 4 的地址倍数?

1:32 位 MCU/MPU/平台 - 小端

几乎相同的例子:

uint8_t arr[] = {0x1,0x2,0x3,0x4,0x5, 0x6, 0x7, 0x8}; //again assume &arr[0] == 0x0
uint32_t *ui32 = (uint32_t*)&arr[1];

*ui32 的值是多少?

我知道 32 位变量应该驻留在 4 的倍数地址中。

我在哪里可以找到这方面的规范?

最佳答案

语言律师

您的代码包含未定义的行为并且不可移植。例如,在我编写过的一些 UNIX 工作站上,内存访问必须与操作数的大小对齐,因此大多数情况下(但不是所有情况下),我会尝试取消引用 (uint32_t*)&arr[1]。会使程序崩溃 SIGBUS , 由内存总线引起的硬件错误。编译器允许你那样搬起石头砸自己的脚。像您那样转换指针违反了 C 的严格别名规则,这会导致未定义的行为

您可以通过编写 uint32_t x; memcpy( &x, &array[1], sizeof(x) ) 来解决这个问题。 ,标准明确允许。从这一点开始,我将假设您正在做与此相同的事情。如果您没有在数组中使用偏移量,您也可以在 C 中使用 union 字段进行 type=pun(尽管 C++ 中的规则不同)。

按照标准,数组的元素必须连续存储,元素之间没有填充。 memcpy()在某些对象之间 x和一组 unsigned char[sizeof(x)]是合法的,结果称为它的对象表示

将任意位复制到 <stdint.h> 中任何精确宽度类型的对象表示与 memcpy()未指定的行为,而不是未定义的行为。这是一个格式良好的程序,你会得到一些有效的 uint32_t脱离它,即使语言标准没有说明必须是什么。您没有授予编译器做任何它想做的事情的权限,比如 Kill All Humans。这只是因为标准不允许精确宽度整数类型具有值位以外的任何位,因此,它们不能有陷阱表示,如果复制到无效位模式会导致未定义的行为该类型的值。 (标准中的示例是在每个字中存储奇偶校验位的实现。)

但是,该保证的另一面是类型 uint8_tuint32_t不能保证存在,并且在现实世界中存在一些架构,它们的符合版本永远不会存在。 (但是,unsigned char array[sizeof(uint_least32_t) + 1] 保证有效。)

Tl;dr

正确运行该代码的真实世界小端实现可能会告诉您 *u320x05040302 .否则,我们会称它为 little-endian 以外的名称。然而,一些编译器让程序员有责任仔细遵守严格的别名规则。众所周知,它们会生成优化代码,如果您通过任何一个指针编写,这些代码都不会达到您的预期。

关于在 8 位平台或 32 位平台上将 uint8_t 的元素转换为 32 位变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51067405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com