c++stlc++20allocatorreinterpret-cast

Why C++ allocators use reinterpret_cast and how to avoid it?


I was trying to implement my own small allocator for testing purposes, and while designing it I thought that I don't know how to implement it without violating strict aliasing rule.

In most open-source from GitHub, C++ allocator method allocate<T> is an adapter to memory: it runs to the memory, asks for N consecutive std::bytes or unsigned chars, and then reinterpret_cast's this memory to T, and after that gives the memory back to its callee.

However, how does that not break the strict aliasing rule (even though the callee must call constructors itself, we cast std::byte* to T*). How is it possible to work-around it when implementing a simple buffer allocator that's suitable for most STL containers?


Solution

  • Strict aliasing is violated when you pretend that there's an object at a certain memory location, but in reality there isn't. (You do that by reinterpret_casting a pointer/reference and then dereferencing it, where only the deferencing itself is UB.)

    It doesn't stop you from using placement-new to change what type of object is stored in some memory, and then accessing it.

    For example:

    #include <string>
    
    int main()
    {
        alignas(std::string) char buf[sizeof(std::string)];
    
        *reinterpret_cast<std::string*>(buf) = "foo"; // UB
    
        std::string *ptr = new(buf) std::string;
        *ptr = "foo"; // Legal.
    }