gpt4 book ai didi

c - 标准定义了什么类型的双关语/指针魔术?

转载 作者:太空狗 更新时间:2023-10-29 15:42:00 29 4
gpt4 key购买 nike

我似乎无法理解 C 标准的某些部分,所以我来这里是为了清除当我必须考虑这些技巧是定义的行为以及哪些是未定义的或违反标准。我不在乎它是否会起作用,我在乎 C 标准是否认为它是合法的、定义的行为。

像这样,我相当确定是 UB:

struct One
{
int Hurr;
char Durr[2];
float Nrrr;
} One;

struct Two
{
int Hurr;
char Durr[2];
float Nrrr;
double Wibble;
} Two;

One = *(struct One*)&Two;

这不是我要说的全部。例如将指向 One 的指针转换为 int*,并取消引用它等。我想很好地了解这些东西的定义,以便我可以在晚上 sleep 。如果可以的话,引用标准中的地方,但一定要指定它是 C89 还是 C99。恕我直言,C11 太新了,不能相信这些问题。

最佳答案

C99 6.7.2.1 说:

第 5 段

As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence



第 12 段

Each non-bit-field member of a structure or union object is aligned in an implementation-defined manner appropriate to its type.



第 13 段

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. 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. There may be unnamed padding within a structure object, but not at its beginning



最后一段涵盖了您的第二个问题(将指向 One 的指针转换为 int*,并取消引用它)。

第一点 - 将 Two* “Downcast”为 One* 是否有效 - 我找不到具体解决的问题。归结为其他规则是否确保 One 的字段和 Two 的初始字段的内存布局在所有情况下都相同。

成员必须按顺序打包,开头不允许填充,并且必须根据类型对齐,但​​标准实际上并没有说布局需要相同(即使在大多数编译器中我我确定是)。

但是,有一种更好的方法来定义这些结构,以便您可以保证:
struct One
{
int Hurr;
char Durr[2];
float Nrrr;
} One;

struct Two
{
struct One one;
double Wibble;
} Two;

您可能认为您现在可以安全地将 Two* 转换为 One* - 第 13 段是这样说的。然而 strict aliasing 可能会在不愉快的地方咬你。但是对于上面的示例,您无论如何都不需要:
One = Two.one;

关于c - 标准定义了什么类型的双关语/指针魔术?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21717027/

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