Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
218 views
in Technique[技术] by (71.8m points)

Is aliasing of pointers between aggregate C structs and their members standards-compliant?

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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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"]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...