
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...