别名与指针到结构数组在不违反标准 [英] Aliasing array with pointer-to-struct without violating the standard

查看:122
本文介绍了别名与指针到结构数组在不违反标准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这我明白了,你可以别名结构(不违反标准,即是),如果他们有兼容的成员,也就是说给定下面的结构:

Reading this I understood that you can alias structures (without violating the standard, that is) if they have compatible members, i.e given the following struct:

typedef struct {
    uint32_t a;
    uint32_t b;
} Frizzly;

下面将打破走样规则:

The following would break aliasing rules:

uint32_t foo(uint16_t *i) {
    Frizzly *f = (Frizzly *)i;
    return f->a;
}

不过,下面这些:

But the following would not:

uint32_t foo(uint32_t *i) {
    Frizzly *f = (Frizzly *)i;
    return f->b;
}

由于有问题的都汇集型包含与我们正在浇铸成的,即指向类型指针类型兼容 uint32_t的可铸造成结构包含键入 uint32_t的的成员(或成员)没有打破别名规则。

because the "aggregrate type" in question contains types compatible with the pointer that that we're casting into it, i.e. a pointer to type uint32_t can be casted into a struct that contains members (or a member) of type uint32_t without breaking aliasing rules.

首先,我才正确地理解这一点?

First, did I understand this correctly?

其次,莫非结构之内的(其他)变量的顺序和类型?也就是说,如果 Frizzly 定义如下:

Secondly, does the ordering and types of the (other) variables within the struct matter? Say, if Frizzly was defined as follows:

typedef struct {
    uint16_t b[2];
    uint32_t a;
}

在第二个例子中投, B 现在是由不兼容的内存支持(<​​code> uint32_t的)类型之后。是投仍然有效(或者说,通过铸造指针访问值)?将更改为任一​​元素 A 修改的第一个元素的值i (以及其他方式),就好像严格别名被禁用?

After the cast in the second example, b is now backed by memory of incompatible (uint32_t) type. Is the cast still valid (or rather, accessing the values through the casted pointer)? Will changes to either element of a alter the value of first element of i (and the other way around) as though strict aliasing were disabled?

另外,如果上面是有效的,如果我有像这样一个结构:

Also, if the above is valid, what if I had a struct like so:

typedef struct {
    void *m;
    uint16_t hooah[4];
} Bar;

下面就投,如果我是正确的,打破走样规则:

The following cast would, if I'm correct, break aliasing rules:

void test(char *boo, size_t dee) {
    Bar *bar = (Bar *)(boo + dee);
    do_other_stuff(bar);
}

我能做出有效的投只需添加一个 unsigned char型成员进入结构?换句话说,不兼容的类型转换指针通常破坏重叠规则,但由于从指针强制转换为包含类型的成员的结构 X 成一个指向 X 是一个例外,可以从指针到-X汇集起来-Y任何投取得有效只需添加X类型的(可能是假的)成员为Y?

Could I make the cast valid simply by adding a single unsigned char member into the struct? In other words, casting pointers of incompatible types generally breaks aliasing rules, but since a cast from a pointer to a struct containing a member of type X into a pointer to X is an exception, can any cast from pointer-to-X to aggregrate-Y made valid simply by adding a (possibly dummy) member of type X into Y?

(我其实没有一个编译测试上述code段)。

(I didn't actually test the above code snippets in a compiler.)

编辑:

我知道我的用词和例子可能会比较差,所以我会尝试重组的问题:如果我理解正确的,这是合法的一个指针到结构到别名类型的X元素的数组只要结构包含类型'X'的成员。现在,提领该结构的成员时,是否该成员必须是类型'X',还是有例外的的所有的结构体的成员,无论其类型为作出严格别名规则只要有合适的类型中的一员?

I know my wording and examples might be rather poor, so I'll try to rephrase the question: if I understood correctly, it is legal for a pointer-to-struct to alias an array of elements of type 'X' as long as the struct contains members of type 'X'. Now, when dereferencing a member of the struct, does the member have to be of the type 'X', or are exceptions to the strict aliasing rules made for all members of the struct regardless of their types as long as there is one member of the appropriate type?

推荐答案

据的 ISO / IEC9899 / TC2 部分6.7.2.1,第13段:

According to ISO/IEC9899/TC2 section 6.7.2.1, paragraph 13:

一个指针结构对象,适当的转换,指向其初始成员(如该成员是位字段,然后在它所在的单元),反之亦然。

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

元素可以被访问(第6.5条第7款规定),通过

So as long as you are casting the struct pointer to the pointer type of the first member it should not violate strict aliasing (specified in section 6.5 paragraph 7) an element may also be accessed via

这包括其成员之间的上述类型之一(包括递归,一个子聚集的成员或包含的联合)聚合或联合类型

an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)

但在另一个方向这只作品(通过一个结构指针访问成员,而不是通过一个成员指针访问结构)

but this only works in the other direction (accessing a member via a struct pointer, not accessing a struct via a member pointer)

这篇关于别名与指针到结构数组在不违反标准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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