gpt4 book ai didi

c - 严格别名和强制转换 union 指针

转载 作者:行者123 更新时间:2023-11-30 14:33:20 27 4
gpt4 key购买 nike

我浏览过这个网站,试图弄清楚我对不同 union 的强制转换是否违反了严格别名或其他 UB。

我有数据包通过串行线路传入,我存储/获取它们如下:

union uart_data {
struct {
uint8_t start;
uint8_t addr;
uin16_t length;
uint8_t data[];
};
uint8_t bytes[BUFFER_SIZE];
};

void store_byte(uint8_t byte) {
uart_data->start = byte;
/* and so on with the other named fields. */
}

uint8_t * get_buffer() {
return uart_data->bytes;
}

我的理解是,至少对于 GCC 和 GNU 扩展来说,这是进行类型双关的有效方法。

但是,我随后希望将 get_buffer() 的返回值转换为 uart 不需要了解详细信息的更具体类型的数据包。

union spec_pkt {
struct {
uint8_t start;
uint8_t addr;
uin16_t length;
uint8_t command;
uint8_t some_field;
uint16_t data_length;
uint8_t data[];
};
uint8_t bytes[BUFFER_SIZE];
};

void process(uint8_t *data) {
union specific_pkt *pkt = (union specific_pkt *)data;
}

我记得在某处读过,这是有效的,因为我正在从 union 中存在的类型进行转换,但我找不到来源。

我这样做的理由是我可以拥有一个只需要了解最低级别细节的 uart 驱动程序。我在 MCU 上,所以我只能访问预先分配的数据缓冲区,这样我就不必在缓冲区之间进行 memcpy ,从而浪费空间。在我的应用程序代码中,我可以用比以下更好的方式处理数据包:

uint8_t data[BUFFER_SIZE];

data[START_POS];
data[LEN_POS];
data[DATA_POS];

如果这违反了 SA 规则或者是 UB,我希望有一些替代方案来实现相同的目的。

我在支持未对齐访问的目标上使用 GCC,并且 GCC 允许通过 union 进行类型双关。

最佳答案

标准完全没有指定在什么情况下可以通过类型不是结构或 union 的非字符左值来访问结构或 union 对象。如果人们认识到该标准的目的纯粹是表明编译器何时必须识别对象正在被看似不相关的左值访问,但并不意味着适用于编译器将如果能够看到一种类型的左值或指针用于派生另一种类型,然后使用该左值或指针来访问与第一个类型关联的存储,而不会对该存储进行任何干预冲突操作,则这种省略是有意义的。例如,给定:

struct sizedPointer { int length,size; int *dat; };
void storeThing(struct sizedPointer *dest, int n)
{
if (dest->length < dest->size)
{
dest->dat[dest->length] = n;
dest->length++;
}
}

这样的解释将允许编译器假设 dest->length 不会使用 dest->dat 编写,因为它的值是在 之后观察到的>dest->dat 已形成,但需要编译器识别给定:

union blob { uint16_t hh[8]; uint64_t oo[2]; } myBblob;

像这样的操作

sscanf(someString, "%4x", &myBlob.hh[1]);

在函数返回后,可能会与从 myBlob 派生的任何左值进行交互。

不幸的是,gcc 和 clang 将此规则解释为仅在不这样做会完全破坏语言的情况下强制承认。因为标准不强制要求成员类型左值可以以任何方式使用,并且 gcc 和 clang 已明确声明不应依赖它们做超出标准要求的任何事情,所以对任何有用的支持都应视为由 clang 和 gcc 维护者一时兴起。

关于c - 严格别名和强制转换 union 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59392655/

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