Strict aliasing plus placement new / explicit destructor call

Ian Lance Taylor iant@google.com
Wed Jul 28 10:36:00 GMT 2010


Andrew Haley <aph@redhat.com> writes:

> On 07/28/2010 06:57 AM, Ian Lance Taylor wrote:
>> Justin Lebar <justin.lebar@gmail.com> writes:
>> 
>>> I'm trying to enable -fstrict-aliasing when building Firefox.  One
>>> class in particular is proving difficult to make work properly.  We
>>> use this class for lazily allocating objects on the stack.
>>>
>>> Code is included at the end of this e-mail.  When I compile with -O2
>>> -Wall, I get
>>>
>>>    main.cpp:20: warning: dereferencing pointer ‘this.0’ does break
>>> strict-aliasing rules
>>>
>>> It seems that this warning is due to the cast in ~Lazy().  Note that I
>>> can't rewrite Lazy<T>'s storage as a union because T may have a
>>> constructor -- the whole purpose of the Lazy class is to let me
>>> stack-allocate T without immediately calling its constructor.
>>>
>>> Also, changing
>>>
>>>       T* obj = reinterpret_cast<T*>(bytes);
>>>
>>> to
>>>
>>>       T* __attribute__((may_alias)) obj = reinterpret_cast<T*>(bytes);
>>>
>>> doesn't eliminate the warning.
>>>
>>> I'm out of ideas.  Is there a way to accomplish what I'm trying to do
>>> here without disabling strict aliasing?  I'd hate to give up now.
>> 
>> Your code looks OK to me by the C++ aliasing rules--at least it would
>> look OK if your program actually called construct.  In this case I think
>> the warning is incorrect.  Current mainline does not seem to give that
>> warning.
>
> Yes, the code looks OK to me too.  My worry is that incorrect alias
> analysis may result in incorrect code being generated.  But perhaps
> there's nothing to worry about because the warning is independent of
> the alias analysis used by the compiler.

That's a good point.  It's hard to say without knowing exactly which
version of the compiler is being used.  For some versions of the
compiler, some of the aliasing warnings are based on the same
information that the alias analysis uses.  Even then, the code tends to
work as expected if the object is uninitialized and every access to the
object use the same incorrect type, as seems to be the case here.  That
is, the compiler does not typically discard accesses to memory which use
the wrong type; the problems arise when the same memory is accessed via
two different types, as the compiler does not attempt to keep those
accesses in order.

Ian



More information about the Gcc-help mailing list