gpt4 book ai didi

结构可以为自己的初始成员和唯一成员起别名吗?

转载 作者:太空狗 更新时间:2023-10-29 16:36:22 25 4
gpt4 key购买 nike

例如,这段代码是否有效,或者它是否通过违反别名规则调用了未定义的行为?

int x;
struct s { int i; } y;
x = 1;
y = *(struct s *)&x;
printf("%d\n", y.i);

我的兴趣是使用基于此的技术来开发执行别名读取的可移植方法。

更新:这里是预期的用例,有点不同,但当且仅当上述有效时它才有效:

static inline uint32_t read32(const unsigned char *p)
{
struct a { char r[4]; };
union b { struct a r; uint32_t x; } tmp;
tmp.r = *(struct a *)p;
return tmp.x;
}

GCC 根据需要将其编译为单个 32 位加载,并且它似乎避免了如果 p 实际上指向 char< 以外的类型时可能发生的别名问题。换句话说,它似乎可以作为 GNU C __attribute__((__may_alias__)) 属性的可移植替代品。但我不确定它是否真的定义明确...

最佳答案

我相信这仍然会违反有效的打字规则。您想要访问未通过该类型的表达式显式声明(或在动态分配的情况下通过存储隐式声明)为包含 struct a 的内存位置。

其他答案中引用的任何部分都不能用来逃避这个基本限制。

但是,我相信您的问题有解决方案:使用 __builtin_memcpy(),它甚至在独立环境中也可用(请参阅 manual entry on -fno-builtin)。


请注意,这个问题没有我说的那么明确。 C11 第 6.5 节 §7 告诉我们可以通过左值表达式访问对象,该左值表达式具有在其成员中包含上述类型之一的聚合或 union 类型

C99 基本原理清楚地表明存在此限制,因此指向聚合的指针和指向其中一个成员的指针可能会产生别名。

我相信以第一个例子的方式利用这个漏洞的能力(但不是第二个例子,假设 p 没有碰巧指向一个实际的char [4]) 是一个意想不到的后果,标准只是因为措辞不准确而未能禁止。

另请注意,如果第一个示例是有效的,我们基本上可以将结构类型潜入其他名义类型的语言中。除了具有公共(public)初始子序列的 union 中的结构(即便如此,成员名称也很重要),相同的内存布局不足以使类型兼容。我相信同样的推理也适用于此。

关于结构可以为自己的初始成员和唯一成员起别名吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17384918/

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