Рассмотрим следующий код С++ 14:
#include <cassert>
#include <new>
#include <type_traits>
struct NonStandardLayout
{
// ...
};
int main()
{
using T = NonStandardLayout;
std::aligned_storage_t< sizeof(T), alignof(T) > storage;
T *const valid_ptr = new(static_cast<void *>(&storage)) T;
T *const maybe_ptr = reinterpret_cast<T *>(&storage);
assert(maybe_ptr == valid_ptr); // ???
valid_ptr->T::~T();
return 0;
}
Гарантируется ли это стандартом, что утверждение в примере никогда не завершится неудачно, для любого типа T?
Обсуждение
В последнем стандарте (http://eel.is/c++draft/), я не вижу ссылки на этот конкретный сценарий, но я нашел следующие параграфы, которые возможно, указывает на ответ "да".
Правильно ли мне думать, что
[Expr.new/15]
а также
[New.delete.placement/2]
вместе утверждает, что значение valid_ptr
будет равно адресу storage
, всегда?
Если да, то верно ли, что reinterpret_cast
даст указатель на полностью построенный объект? Потому как,
[Expr.reinterpret.cast/7],
[Expr.static.cast/13]
а также
[Basic.compound/4]
вместе, кажется, указывают, что это должно быть так.
По моим наблюдениям, реализация библиотек распределителя по умолчанию, похоже, похожа на это и без проблем! Действительно ли безопасно делать это?
Как мы можем быть уверены, что оба указателя будут одинаковыми, или мы можем?