可在别名结构自身的最初和唯一的成员? [英] Can a struct alias its own initial and only member?

查看:97
本文介绍了可在别名结构自身的最初和唯一的成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,这是code有效呢,还是由于违反了别名规则未定义行为?

For example, is this code valid, or does it invoke undefined behavior by violating the aliasing rules?

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

我的兴趣是使用基于此技术开发执行走样读取一个便携式的方法。

My interest is in using a technique based on this to develop a portable method for performing aliased reads.

更新:这里是使用目的的情况下,有一点点不同,但它应该是有效的,当且仅当上面是有效的:

Update: here is the intended usage case, a little bit different, but it should be valid if and only if the above is valid:

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 实际指向其他类型可能发生的混淆问题比字符。换句话说,它似乎作为一个便携式替换为GNU C __属性__((__ __ may_alias))属性。但我不确定它是否真的明确...

GCC, as desired, compiles this to a single 32-bit load, and it seems to avoid the aliasing issues that could happen if p actually points to a type other than char. In other words, it seems to act as a portable replacement for the GNU C __attribute__((__may_alias__)) attribute. But I'm uncertain whether it's really well-defined...

推荐答案

我相信这将仍然有效违反类型规则。你想为包含访问,这不是(在动态分配的情况下,或隐式通过存储)显式声明的存储位置结构A 通过的前pression该类型。

I believe this will still violate effective typing rules. You want to access a memory location that wasn't declared explicitly (or implicitly via storage in case of dynamic allocation) as containing a struct a through an expression of that type.

这已经在其他的答案被引用的部分都不可以用来逃离这个基本的限制。

None of the sections that have been quoted in other answers can be used to escape this basic restriction.

不过,我相信有你的问题的解决方案:使用 __ builtin_memcpy(),这是可以甚至在独立的环境中(请参阅手册上 -fno-内置入门 )。

However, I believe there's a solution to your problem: Use __builtin_memcpy(), which is available even in freestanding environments (see the manual entry on -fno-builtin).

请注意,这个问题是有点不太明确的,比我使声音。 C11 6.5节§7告诉我们,它的罚款,通过有一个左值前pression访问对象的,其中包括其成员之间的上述类型之一的聚集或联合类型

Note that the issue is a bit less clear-cut than I make it sound. C11 section 6.5 §7 tells us that it's fine to access an object through an lvalue expression that has an aggregate or union type that includes one of the aforementioned types among its members.

C99的理由讲清楚,这个限制是有这么一个指向骨料和一个指向其成员中的一个可能的别名。

The C99 rationale makes it clear that this restriction is there so a pointer to an aggregate and a pointer to one of its members may alias.

我相信,在第一个例子的方式来利用这个漏洞的能力(不过的的第二个假设 P 不碰巧指向一个实际的char [4] )是一个意想不到的后果,其标准只失败,因为IM precise措辞不允许。

I believe the ability to use this loophole in the way of the first example (but not the second one, assuming p doesn't happen to point to an actual char [4]) is an unintended consequence, which the standard only fails to disallow because of imprecise wording.

另外请注意,如果第一个例子是有效的,我们就基本上可以在结构打字潜入一个名义上类型化的语言。与常见的初始后继一边(即使如此,成员名称做的事)工会的结构,相同容量的内存布局是不足以使类型兼容。我相信,同样的道理也适用于这里。

Also note that if the first example were valid, we'd basically be able to sneak in structural typing into an otherwise nominally typed language. Structures in a union with common initial subsequence aside (and even then, member names do matter), an identical memory layout is not enough to make types compatible. I believe the same reasoning applies here.

这篇关于可在别名结构自身的最初和唯一的成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆