Re: How to use __attribute__((__may_alias__))

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Does anyone have a small example in which __attribute__((__may_alias__)) is necessary and sufficient to generate correct code?

It is a documented feature of gcc that, as documented, exactly fits the situation I am trying to deal with (in a few places). So far as I recall, I have never gotten it to work. If I see even one case where it is necessary and sufficient, I might know what direction to modify my own code (rather than try things blindly).

Andrew Haley wrote:
John Fine wrote:
Working code:

union { DAT* pp; std::size_t dummy; } no_strict_alias;
no_strict_alias.pp =foo();
reinterpret_cast<DAT_PTR*>(&no_strict_alias.pp)->bar(x);

No, this isn't guaranteed to work.  Your data must be *declared* as
union no_strict_alias.  Casting to a pointer to union no_strict_alias
isn't the same unless the only way you ever access your data is via
that cast.
I don't understand your objection. I certainly am worried this construct will stop working in future versions of gcc (though not for the reason you described). I'm getting pretty confident that it works reliably for gcc 4.3.2 because it has fixed every case where I have needed it.

When you said "Your data must be *declared* as union no_strict_alias." were you talking about my example that you quoted?

In that example, the data obviously is declared with the union.

Or were you talking about the more complicated example I mentioned, but you didn't quote even my description of that?

In general:

Problem: there is a specific write to an object, such that the optimizer (after inlining) can see all possible reads from that object and none of those possible reads are compatible data types with the write. So the optimizer removes the write. (If the optimizer cannot see all possible reads, it can't know none are compatible, so it can't remove the write.)

My correction is to do that specific write through one side of a union, where the other side of that union is never used. That seems to cover the full problem in gcc4.3.2

In my most complicated case, the creation of the object was distant, where it was not practical to use the union nor possible for the optimizer to infer anything about subsequent reads or writes. The problem write was in a location where (with a lot of inlining) the optimizer could see the subsequent destruction of the object and all reads (there was only one) that occur before the destruction. That read was impractical to change to use a union, so I discovered changing only the write was enough.

You said "Casting to a pointer to union no_strict_alias isn't the same unless the only way you ever access your data is via that cast".

That may be true for some future version of gcc. I'm not sure what to do them. For now, I think the union works.

But if anyone knows of any case where this one sided union method fails, please tell me.

The key distinguishing factor of this method is that all writes that the optimizer might otherwise eliminate because of strict aliasing are through the union.


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux