Consider the following code:
#include <memory>
template<typename Allocator>
char* allocate_array(Allocator alloc, size_t n)
{
static_assert(std::is_same<typename Allocator::value_type, char>::value);
char* data = alloc.allocate(n);
// (1)
for (size_t i=0; i<n; ++i) {
new (data+i) char();
}
return data;
}
char* copy_array(size_t n, const char* original)
{
char* copy = allocate_array(std::allocator<char>(), n);
// (2)
for (size_t i=0; i<n; ++i) {
copy[i] = original[i];
}
return copy;
}
Is the placement-new initialization marked by (1)
necessary to prevent the program from having undefined behaviour, even if every char is guaranteed to be written to in (2)
before it can be read? Or can it be safely removed?
Note that this is not being optimized away, even at -O3
I see both gcc and clang generating subsequent calls to both memset()
and memcpy()
.