Ian Lance Taylor wrote:
The may_alias attribute is normally applied to a type, not a variable.
It is possible that the attribute got dropped somewhere during
optimization. That would be a bug, but I expect that this case is not
well tested.
I know you said that you didn't want to use a union, but that is what I
would recommend. Using a union need not have any performance impact.
Thankyou. I'll focus more on versions that use a typedef. This
problem, unfortunately, has a VERY slow build and test cycle. Do you
have any opinions on any of the following versions:
Original
DAT* pp=foo();
reinterpret_cast<DAT_PTR*>(&pp)->bar(x);
Idea 1
typedef DAT __attribute__((__may_alias__))* DAT_PTR_ALIAS;
DAT_PTR_ALIAS pp=foo();
reinterpret_cast<DAT_PTR*>(&pp)->bar(x);
Idea 2
typedef DAT* __attribute__((__may_alias__)) DAT_PTR_ALIAS;
DAT_PTR_ALIAS pp=foo();
reinterpret_cast<DAT_PTR*>(&pp)->bar(x);
Idea 3
DAT* pp=foo();
union { DAT** p1; DAT_PTR* p2 } ppp;
ppp.p1 = &pp;
ppp.p2->bar(x);
Fundamentally, I need an object to be both a DAT* and a DAT_PTR, but a
union of those two is impossible because of the constructor and
destructor in the class DAT_PTR. So if I use a union, I only know how
to use a union of DAT** and DAT_PTR*. I don't know if that covers the
situation.
The action that gets optimized away is the store of the result of foo
into pp. The union seems to only protect optimizations of ppp.
The object that needs the protection is pp. That is a DAT* that may be
aliased to something else (so the store into it should not be optimized
away). So "Idea 2" above seems the most logical fit. But I'm getting
confused over which level of indirection is affected by the attribute.
Maybe it needs to be on the other side of the problem, such as:
Idea 4
DAT* pp=foo();
typedef DAT_PTR __attribute__((__may_alias__)) DAT_PTR_ALIAS;
reinterpret_cast<DAT_PTR_ALIAS*>(&pp)->bar(x);