Skip to content

Use a union in Variant for safe type punning

Kenneth Moreland requested to merge kmorel/vtk-m:variant-safe-punning2 into master

Create a VaraintUnion that is an actual C++ union to store the data in a Variant.

You may be asking yourself, why not just use an std::aligned_union rather than a real union type? That was our first implementation, but the problem is that the std::aligned_union reference needs to be recast to the actual type. Typically you would do that with reinterpret_cast. However, doing that leads to undefined behavior. The C++ compiler assumes that 2 pointers of different types point to different memory (even if it is clear that they are set to the same address). That means optimizers can remove code because it "knows" that data in one type cannot affect data in another type. To safely change the type of an std::aligned_union, you really have to do an std::memcpy. This is problematic for types that cannot be trivially copied. Another problem is that we found that device compilers do not optimize the memcpy as well as most CPU compilers. Likely, memcpy is used much less frequently on GPU devices.

Edited by Kenneth Moreland

Merge request reports