Is aliasing of pointers between aggregate C struct

2019-09-11 00:17发布

Is the following a standards-compliant C program (and by which standard(s))? If it is non-compliant (by breaking the strict aliasing rule or otherwise) is it "safe" with respect to GCC or any other commonly-used C compiler?

int main()
{
    typedef struct {
       int data;
    } Type1;

    typedef struct {
       float data;
    } Type2;

    typedef struct {
       Type1 type1;
       Type2 type2;
    } Aggregate;

    Aggregate aggregate;
    aggregate.type1.data = 1;
    aggregate.type2.data = 2.0;

    Aggregate *p_aggegregate = &aggregate;
    Type1     *p_type1       = (Type1*) &aggregate;
    Type2     *p_type2       = (Type2*) &aggregate;

    int   data1 = p_type1->data;
    float data2 = p_type2->data;

    return 0;
}

1条回答
Emotional °昔
2楼-- · 2019-09-11 00:48

Strictly spoken, your program is standard compliant (C11, C99, dunno about K&R). It contains only pointer conversions and there are very little rules in the C standard which are restricting it

Your

Type1     *p_type1       = &aggregate;
Type2     *p_type2       = &aggregate;

breaks type safety and probably every compiler will warn about it as an invalid type conversion. But it is covered by

7 A pointer to an object type may be converted to a pointer to a different object type. [6.3.2.3 "Pointers", C11 draft]

I have not found a rule which requires an explicit cast

Type1     *p_type1       = (Type1 *)&aggregate;

and paragraph above uses a similar wording like paragraph 1 one which allows the commonly used implicit something to/from void * conversion.

Access to both variables is valid because &aggregate == &aggregate.type1.

But as said, it is a really bad and unsafe style to write things in this manner and usual coding styles will consider this as an error. Access will be undefined when you add e.g. a char foo; attribute before type1.

EDIT:

Program is invalid; it violates

— the left operand has atomic, qualified, or unqualified pointer type, and [...] both operands are pointers to qualified or unqualified versions of compatible types [...] [6.5.16.1 "Simple assignment"]

with

2 For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types. [6.7.6.1 "Pointer declarators"]

查看更多
登录 后发表回答