1

I ran to an over-specialized container somewhere in production code. It was C++98 upgraded to C++11, but I wonder how many UBs (or implementation-defined behaviors) are in it. Basically, without any useful interfaces the idea boils down to this:

template<class T>
class Box {
public:
    using DataType = T;

    Box() : sz(def_size), data_ptr(allocate(def_size)) {}

    T* data() { return reinterpret_cast<T*>(data_ptr); }

protected:
     using BlockType = alignas(alignof(T)) char[sizeof(T)];

     BlockType * allocate(size_t sz) {
        BlockType* ptr = new BlockType[sz];
        for(auto p = ptr, ptrE = ptr + sz; ptr != ptrE; ++ptr ) {
            auto* obj = new(p) T;
            // do some initialization on obj
        } 
        return  ptr;
    }
private:
    size_t     sz;
    BlockType *data_ptr;
};

One I can think of: compiler is not required to implement that kind of over-alignment. A cross-compiler used for project did.

But did the C++ standard define the use of pointer arithmetics on the value returned by data() as a pointer to an element of an array? Pointers to blocks aren't necessary to be pointers to instances of T?

1
  • In data() you should either return ptr got from the placement new or call std::launder before you return the type-casted pointer Commented Mar 26 at 10:58

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.