Re: [boost] gcc-4.4.0 and boost::optional is giving (spurious?) strict-aliasing warnings

On Thu, May 7, 2009 at 3:37 AM, Kim Barrett <kab.conundrums@verizon.net> wrote:
I'm not 100% sure, but this could be very wrong as, IIRC, there is no guarantee that for non PODS the address of the first element (i.e. aligned_storage.data_) is the same as 'this'. but why doesn't aligned storage implements address() as: void * address { return this.data_.data_.buf; } BTW, I see that boost optional actually uses its own implementation of aligned storage, whose address member function returns a pointer to a char buffer, so it shouldn't be a problem.
IIRC aliasing rules talk about dynamic types of objects: roughly, you can access a memory location only with a type which is the same as the *dynamic type* of that location or as a char array. Boost optional does an explicit placement new of the stored type on the buffer which changes the dynamic type of the buffer so it should be safe from a standard point of view. Before reusing the buffer It invokes the destructor of the type, which ends the object lifetime. That said, gcc has been known to miscompile placement new from time to time (but it should be more or less fixed on recent versions: it pretty much acts as a compiler optimization barrier). In the end, IMHO the warning is spurious and could be safely ignored (modulo compiler bugs).
I do not think this rule actually help you: you can't still read from a field different from the last written to (except for some exceptions like structures with common initial sequences.) Most compilers give additional guarantees, though.
I do not see how this helps, first of all sizeof(*data) is illegal (sizeof(void) doesn't make any sense, gcc defines it as 1 as an extension), then how copying one byte will fix aliasing problems?
I do not think it really strips away the type of the destination: in fact it is often unsed to bit cast from integers to float and back: if a memcpy(&some_float, &some_integer, sizeof(int32_t)) really did change the type of some_float, it would break a lot of code (you could no longer threat some_float as a float). What is guarateed is that some_float will contain the same bit pattern of some_integer, while still maintaining the float type. It assumes that the bit pattern of the source is a valid pattern for the destination type, otherwise it is UB.
[And yes, I agree that this is rather grotesque.]
Aliasing rules really are a mess. -- gpd

Hi All, Sorry but I just couldn't find time to answer this before.
Indeed.. whose code is not like the one above.
whose address member function returns a pointer to a char buffer, so it shouldn't be a problem.
Precisely... a char* is explcitely allowed to alias any object, so, for Boost.Optional at least, the warning is clearly spurious.
static_cast<internal_type*>( static_cast<void*>( <a char*> )) which should not raise any strict aliasing warnings
Via a char*, so the placement new is merely taking the address of a suitably aligned memory block.
which changes the dynamic type of the buffer
Just for the record, no it doesn't. Best -- Fernando Cacciola SciSoft Consulting, Founder http://www.scisoft-consulting.com

On Fri, May 15, 2009 at 9:11 PM, Fernando Cacciola <fernando.cacciola@gmail.com> wrote: [ the following text was by me] z>>
Wait, how it doesn't? It uses placement new. The lifetime of an object, and thus its type begins at the new expression and ends when deleted. Initially the buffer of an optional<T> certainly hasn't type T (in fact, being an union, the type would be undetermined until the first store to a member of the union), but when placement new T is used and the object is constructed, the buffer certainly has type T. As the type is a property of the object, when the object is deleted, the buffer certainly no longer has that type. So I think you can say that, in optional at least, placement new changes the type of the buffer, from undetermined to T. Am I missing something? -- gpd

On 2009-05-15 21:11, Fernando Cacciola wrote:
Has this issue been reported to gcc, then? I searched their bugzilla and didn't find anything relevant. I'm also curious whether someone has found a workaround for this. I'd like to patch optional.hpp, so I can keep building with -Werror. Regards, Thomas Sondergaard
participants (3)
-
Fernando Cacciola
-
Giovanni Piero Deretta
-
Thomas Sondergaard