Рассмотрим следующий код:
#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;
}
Является ли инициализация новой позиции, отмеченная (1)
, необходимой для предотвращения неопределенного поведения программы, даже если гарантируется, что каждый символ будет записан в (2)
прежде чем его можно будет прочитать? Или это можно безопасно удалить?
Обратите внимание, что это не оптимизируется, даже на -O3
Я вижу, как gcc и clang генерируют последующие вызовы к memset()
и memcpy()
.