Is constructing objects in a char array well-formed

Viewed 167

This is almost standard textbook use of placement new

template<size_t Len, size_t Align>
class aligned_memory
{
public:
    aligned_memory() : data((char*)(((std::uintptr_t)mem + Align - 1) & -Align)) {}
    char* get() const {return data;}
private:
    char mem[Len + Align - 1];
    char* data;
};

template<typename T, size_t N>
class Array
{
public:
    Array() : sz(0) {}
    void push_back(const T& t)
    {
        new (data.get() + sz++ * sizeof(T)) T(t);
    }
    void pop_back()
    {
        ((T*)data.get() + --sz)->~T();
    }

private:
    aligned_memory<N * sizeof(T), alignof(T)> data;
    size_t sz;
};

Seems pretty fine, until we look into strict-aliasing, there seems to be some conflict in whether this is well-formed

Camp ill-formed

Camp well-formed

They all agree on char* may always reference another object, but some point out its ill-formed to do so the other way round.

Clearly our char[] converts to char* then casted to T*, with which it is used to call its destructor.

So, does the above program break the strict-aliasing rule? Specifically, where in the standard does it says it is well-formed or ill-formed?

EDIT: as background info, this is written for C++0x, before the advent of alignas and std::launder. Not asking specifically for a C++0x solution, but it is preferred.

alignof is cheating, but its here for example purposes.

2 Answers
Related