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
- C++'s Strict Aliasing Rule - Is the 'char' aliasing exemption a 2-way street?
- Strict aliasing rule and 'char *' pointers
Camp well-formed
- Does encapsulated char array used as object breaks strict aliasing rule
- How to avoid strict aliasing errors when using aligned_storage
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.