gpt4 book ai didi

c - 指针和指针数组的并集是否保证单个指针与数组的第一个元素具有相同的地址?

转载 作者:太空宇宙 更新时间:2023-11-03 23:37:11 25 4
gpt4 key购买 nike

结构体:

struct stree {
union {
void *ob;
struct stree *strees[256];
};
};

C 标准(尤其是 C11)是否保证 obstree[0] 的别名?

最佳答案

也许吧。 C 标准仅保证以下内容,6.3.2.3:

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.

理论上/形式上,void* 不需要具有与指向对象的指针相同的内存表示。每当遇到此类转换时,理论上它都可以采取一些技巧,例如跟踪原始值,以便稍后恢复。

实际上,void* 和对象指针在任何健全的系统上都具有相同的大小和格式,因为这是迄今为止满足上述要求的最简单方法。存在具有对象扩展寻址模式的系统,但它们并不像 C 标准预期的那样工作。相反,他们通过发明 nearfar 指针限定符来使用非标准扩展,然后可以将其应用于 void* 或对象指针。 (这方面的一些例子是低端微 Controller 和旧的 MS DOS。)

底线:针对疯狂或虚构系统的可移植性进行设计是在浪费大量时间。加入 static_assert(sizeof(void*) == sizeof(int*), "...") 就足够了。因为实际上您不会找到具有神奇或神秘的 void* 格式的系统。如果你这样做,那就处理它。

但是你要记住的是,void* 本身是一种不同的类型,所以你通常不能访问 void* 所在的内存通过另一种指针类型(严格指针别名)存储。但是严格的别名规则也有一些异常(exception),通过 union 进行类型双关就是其中之一。

因此关于您的unionvoid* 和第一个对象指针保证从相同的地址开始分配,但是它们各自的大小内部格式可以理论上是不同的。在实践中,您可以假设它们是相同的,并且因为您使用了 union,所以您没有违反严格的别名。

至于最佳实践,首先要避免 void*,因为很少有地方真正需要它们。对于需要传递一些通用指针的少数情况,通常最好使用 uintptr_t 并将结果存储为整数。

关于c - 指针和指针数组的并集是否保证单个指针与数组的第一个元素具有相同的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56684299/

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