John Fine <johnsfine@xxxxxxxxxxx> writes: > 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. When you can't use a union, another option is memcpy. > 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); The may_alias attribute should be on the type to which things point. SO you want something like typedef DAT __attribute__ ((__may_alias__)) DAT_ALIAS; and then use DAT_ALIAS*. Ian