考虑以下C++14代码:
这个例子中的assert语句对于任何类型T都不会失败,是否有标准保证?
讨论
查看最新的标准(http://eel.is/c++draft/),我没有找到对这种特定情况的参考,但我发现以下段落可能表明答案是“是”。
我是否正确地认为[expr.new/15]和[new.delete.placement/2]一起声明
如果是这样,
根据我的观察,库实现的默认分配器似乎会进行类似的转换而不必担心!像这样强制转换真的安全吗?
我们怎样才能确定这两个指针是否相同,或者我们能吗?
#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;
}
这个例子中的assert语句对于任何类型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]似乎都表明应该是这样的。根据我的观察,库实现的默认分配器似乎会进行类似的转换而不必担心!像这样强制转换真的安全吗?
我们怎样才能确定这两个指针是否相同,或者我们能吗?
malloc
保证返回任何数据类型对齐的内存。 - Jean-François Fabrereinterpret_cast
的结果可以是任何指针值,除了空指针,因为它没有被使用。除了与空指针比较之外,唯一有保证的用法是将其强制转换回来。 - Cheers and hth. - Alfstd::aligned_storage_t
的定义。如果它保证了这个属性,那么是的。这与放置 new 如何工作无关。 - Kirill Kobelevstd::launder
的动机之一(另一半是Core 1776)。 - T.C.