Subject: Re: [boost] [interest] underlying type library
From: Mathias Gaunard (mathias.gaunard_at_[hidden])
Date: 2011-08-21 17:18:16


On 08/21/2011 09:23 PM, Julian Gonggrijp wrote:

> However, as Vicente Botet (and Alexander Stepanov) pointed out, there
> are still valid use cases for the bitwise move_raw mechanism.

Care to point out one that wouldn't be better handled by move constructors?

> It's impossible to realise in current C++, but conceptually it exists.
> To be honest I think a built-in underlying type function (and real
> type functions in general) would make a very interesting addition to
> C++.

The layout of non-PODs is completely implementation-defined. Therefore
there couldn't be anything meaningful for "underlying type". All it
could be is a sequence of bytes of a certain size with a certain alignment.

>> Also I assume move_raw here is memcpy. If it isn't, you have strict aliasing problems as well.
>
> In my current implementation move_raw is the compiler_generated POD
> assignment (the 'overlying type' is reinterpret_cast to the underlying
> type to enable this).

Right, this is what I suspected.
Your code is therefore invalid, and may very well break when you enable
optimizations (or not, depending on what the compiler chooses to do).

> could you give me a quick explanation of strict aliasing
> problems and how they come into being if I don't use memcpy?

Compilers are free to consider that pointers of unrelated types may
never alias (with certain exceptions).

This means that it is not allowed to perform a write to an object
through a pointer of a different, unrelated, type.

For more details, consult the standard.

In particular,

float f;
*(uint32_t*)&f = 0;

is not allowed, even though both types are PODs and of the same size
(I'm assuming sizeof(float) is 4 and CHAR_BIT is 8).

Notice how GCC will warn you in this case:
warning: dereferencing type-punned pointer will break strict-aliasing rules

But it's not because GCC doesn't warn you that there aren't any problems...