gpt4 book ai didi

c - 灵活的数组成员访问 union 原始字节

转载 作者:行者123 更新时间:2023-12-01 15:34:57 25 4
gpt4 key购买 nike

在嵌入式平台上。

假设我通过串行线路从从设备接收字节,其中数据被正确序列化和反序列化,以确保数据的字节序和大小正确。

我真正想要实现的是具有可变大小的struct test,以允许将来扩展数组成员。

  • 多平台应用程序上是否存在意外行为?
  • C 标准中是否有部分禁止此类访问?

#include <stdio.h>
#include <stdint.h>

struct test
{
uint32_t a;
uint32_t b;
uint32_t c[];
};

union test1
{
struct test A;
uint8_t B[256];
};

int main(void)
{
union test1 test2;

for (uint32_t i=0; i<256; i++)
{
test2.B[i] = i;
}

for (size_t i=0; i<(sizeof(test2.B)/sizeof(uint32_t))-2; i++)
printf("Test: 0x%08X\n", test2.A.c[i]);
}

最佳答案

需要考虑的一些事情:

  • 对齐。您不能简单地假设结构体或 union 体不会有填充字节。理论上,某些与 int 大小相关的对齐要求模糊的系统可能会导致结构体内部填充字节。

    由于这种情况主要是理论上的,因此您可以通过添加来确保它不会发生

    _Static_assert(sizeof(struct test) == sizeof(int)+sizeof(int),
    "Padding detected!");
  • 正如问题中所指出的,Endianess 是一个真正令人担忧的问题,必须在某个地方进行处理。

  • Signed int 可能在 union 中没有任何意义,或者在嵌入式系统中的任何其他地方都没有任何意义。这些可能会在很多方面造成严重破坏,但不会在发布的任何代码中造成破坏。它们应该替换为 stdint.h 中确定性大小和符号的类型。
  • 类型双关语。尽管是实现定义的,但类型双关语很好。我不明白为什么你的代码会在常规的二进制补码系统上引起问题。但从理论上讲,您可能会遇到不使用二进制补码但实现填充位、陷阱位等的奇异系统的可移植性问题。我不会过度担心这种几乎不存在的系统的可移植性。
  • C 标准。显然您无法将灵活的数组成员代码移植到 C90 系统。它可能会在那里编译但会调用未定义的行为。此外,标准委员会的一些迟钝分支在 C11 中将 stdint.h 设为可选。不过我不会担心这个。

总的来说,我想说代码很好并且可以移植到所有有用的系统,只要您在某处处理字节顺序并摆脱int

关于c - 灵活的数组成员访问 union 原始字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40304485/

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