gpt4 book ai didi

比较结构指针、丢弃成员和 UB

转载 作者:行者123 更新时间:2023-12-03 18:39:53 26 4
gpt4 key购买 nike

考虑以下代码:

int main()
{
typedef struct { int first; float second; } type;

type whole = { 1, 2.0 };
void * vp = &whole;

struct { int first; } * shorn = vp;
printf("values: %d, %d\n", ((type *)vp)->first, shorn->first);
if (vp == shorn)
printf("ptrs compare the same\n");

return 0;
}
两个问题:
  • 是指针相等比较 UB 吗?
  • 关于在初始化 second 的行上“剪切”掉 shorn 成员:像这样丢弃结构成员然后取消引用操纵的指针以访问剩余成员的 C 是否有效?
  • 最佳答案

    C 标准的 6.2.5 类型 28 部分说:

    [...] All pointers to structure types shall have the same representation and alignment requirements as each other. [...]


    部分 6.3.2.3 指针 段落 1 说:

    A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.


    7 段说:

    A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned68) for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. [...]


    脚注 68 说:

    In general, the concept "correctly aligned" is transitive: if a pointer to type A is correctly aligned for a pointer to type B, which in turn is correctly aligned for a pointer to type C, then a pointer to type A is correctly aligned for a pointer to type C.


    因为所有指向结构类型的指针都具有相同的表示,所以指向 void 的指针和指向结构类型的指针之间的转换对于所有指向结构类型的指针必须相同。因此,似乎指向结构类型 A 的指针可以通过强制转换运算符直接转换为指向结构类型 B 的指针,而无需中间转换为指向 void 的指针,只要该指针对于结构类型 B 是“正确对齐的”。(这可能是一个弱论点。)
    问题仍然存在,在两个结构类型 A 和 B 的情况下,其中结构类型 A 的初始序列由结构类型 B 的所有成员组成,结构类型 A 的指针保证与结构类型 B 正确对齐(显然不能保证相反)。据我所知,C 标准没有做出这样的保证。因此严格来说,指向较大结构类型 A 的指针可能不会与较小的结构类型 B 正确对齐,如果不是,则行为未定义。对于“理智”的编译器,较大的结构类型 A 不会比较小的结构类型 B 具有更弱的对齐,但对于“疯狂”的编译器,情况可能并非如此。

    关于使用派生自完整(较长)结构的指针访问截断(较短)结构的成员的第二个问题,那么只要指针正确对齐较短的结构(请参阅上文了解为什么这可能不适用于一个“疯狂的”编译器),并且只要避免严格的别名规则(例如,通过在跨编译单元边界的中间外部函数调用中通过一个指向 void 的中间指针),然后通过指向较短的指针访问成员结构类型应该完全没问题。当两种结构类型的对象作为同一 union 类型的成员出现时,有一个特殊的保证。 6.3.2.3 结构和 union 成员 6 说:

    One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the unionobject currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the unionis visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.


    但是,由于结构类型内成员的偏移量不取决于该结构类型的对象是否出现在 union 类型中,因此上述暗示任何具有共同初始成员序列的结构都将在各自结构类型内的相同偏移量。

    关于比较结构指针、丢弃成员和 UB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63175051/

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