基于unsigned char[]的隐式对象创建:reinterpret_cast至隐式对象是否合法?(P0593)
关于C++隐式对象创建与reinterpret_cast、std::launder的疑问
由P0593R6引入的隐式对象创建机制已纳入C20标准,且可回溯应用至更早的C版本。论文中给出如下示例代码,称该机制可使这类代码合法:
unique_ptr<char[]> Stream::read() { // ... 确定数据大小 ... unique_ptr<char[]> buffer(new char[N]); // ... 将数据复制到buffer中 ... return buffer; } void process(Stream *stream) { unique_ptr<char[]> buffer = stream->read(); if (buffer[0] == FOO) process_foo(reinterpret_cast<Foo*>(buffer.get())); // #1 else process_bar(reinterpret_cast<Bar*>(buffer.get())); // #2 }
在隐式对象创建规则出台前,这类代码因未显式创建Foo或Bar对象,属于未定义行为(UB)。新规则规定:若存在能让代码行为合法的方式,对应的Foo/Bar对象会被隐式创建。
但此处存在几个核心疑问:
- 仅通过
reinterpret_cast转换指针,是否足以获取指向隐式创建的Foo/Bar对象的有效指针?代码是否仍可能存在潜在的UB? - 即便
Foo/Bar对象已被隐式创建,它们与缓冲区首元素char并不具备指针可互换性(pointer-interconvertible)。reinterpret_cast转换后的指针值仍指向数组首元素,只是类型被修改了。这种情况下,是不是必须使用std::launder才能让代码完全合法? - 论文示例中并未使用
std::launder,这是否属于疏漏?
该问题还与解决反向转换问题的P1839提案相关。
内容的提问来源于stack exchange,提问作者JMC
相关产品推荐
相关产品推荐

