gpt4 book ai didi

c - 在不违反标准的情况下使用指向结构的指针对数组进行别名

转载 作者:太空狗 更新时间:2023-10-29 17:04:19 26 4
gpt4 key购买 nike

阅读 this我知道如果结构具有兼容的成员,您可以为结构起别名(即不违反标准),即给定以下结构:

typedef struct {
uint32_t a;
uint32_t b;
} Frizzly;

以下会破坏别名规则:

uint32_t foo(uint16_t *i) {
Frizzly *f = (Frizzly *)i;
return f->a;
}

但以下不会:

uint32_t foo(uint32_t *i) {
Frizzly *f = (Frizzly *)i;
return f->b;
}

因为所讨论的“聚合类型”包含与我们正在转换到它的指针兼容的类型,即指向类型 uint32_t 的指针可以被转换到包含成员(或uint32_t 类型的成员)而不违反别名规则。

首先,我是否理解正确?

其次,结构中(其他)变量的顺序和类型是否重要?比如说,如果 Frizzly 定义如下:

typedef struct {
uint16_t b[2];
uint32_t a;
}

在第二个示例中的转换之后,b 现在由不兼容 (uint32_t) 类型的内存支持。强制转换是否仍然有效(或者更确切地说,通过强制转换的指针访问值)?对 a 的任一元素的更改是否会改变 i 的第一个元素的值(反之亦然),就像禁用严格别名一样?

此外,如果上述内容有效,如果我有这样的结构会怎样:

typedef struct {
void *m;
uint16_t hooah[4];
} Bar;

如果我是正确的,下面的转换将打破别名规则:

void test(char *boo, size_t dee) {
Bar *bar = (Bar *)(boo + dee);
do_other_stuff(bar);
}

我是否可以通过将单个 unsigned char 成员添加到结构中来使转换有效?换句话说,转换不兼容类型的指针通常会破坏别名规则,但是由于从指向包含类型 X 的成员的结构的指针转换为指向 X 的指针是一个异常(exception),从指针到 X 到聚合 Y 的任何转换是否可以通过将 X 类型的(可能是虚拟的)成员添加到 Y 中来使有效?

(我实际上并没有在编译器中测试上面的代码片段。)

编辑:

我知道我的措辞和示例可能相当糟糕,所以我将尝试重新表述这个问题:如果我理解正确,则指向结构的指针为“X”类型的元素数组别名是合法的只要该结构包含“X”类型的成员。现在,当取消引用结构的成员时,该成员是否必须是“X”类型,或者是为结构的所有成员制定的严格别名规则的异常(exception),无论它们的类型如何只要有一个适当类型的成员?

最佳答案

根据 ISO/IEC9899/TC2第 6.7.2.1 节第 13 段:

A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa

因此,只要您将结构指针转换为第一个成员的指针类型,它就不应违反严格的别名(在第 6.5 节第 7 段中指定)元素也可以通过访问

an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)

但这只适用于另一个方向(通过结构指针访问成员,而不是通过成员指针访问结构)

关于c - 在不违反标准的情况下使用指向结构的指针对数组进行别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17007146/

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