【发布时间】:2011-05-24 00:35:30
【问题描述】:
我很确定这段代码应该是非法的,因为它显然不起作用,但它似乎是 C++0x FCD 允许的。
class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X(); // according to the standard, the RHS is a placement-new expression
::operator delete(p); // definitely wrong, per litb's answer
delete p; // legal? I hope not
也许你们中的一位语言律师可以解释标准是如何禁止这样做的。
还有数组形式:
class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X[1]; // according to the standard, the RHS is a placement-new expression
::operator delete[](p); // definitely wrong, per litb's answer
delete [] p; // legal? I hope not
This is the closest question我找到了。
编辑:我只是不相信标准语言限制函数void ::operator delete(void*) 的参数以任何有意义的方式应用于删除表达式 中delete 的操作数。充其量,两者之间的联系是非常脆弱的,并且许多表达式被允许作为delete 的操作数,这些表达式对于传递给void ::operator delete(void*) 是无效的。例如:
struct A
{
virtual ~A() {}
};
struct B1 : virtual A {};
struct B2 : virtual A {};
struct B3 : virtual A {};
struct D : virtual B1, virtual B2, virtual B3 {};
struct E : virtual B3, virtual D {};
int main( void )
{
B3* p = new E();
void* raw = malloc(sizeof (D));
B3* p2 = new (raw) D();
::operator delete(p); // definitely UB
delete p; // definitely legal
::operator delete(p2); // definitely UB
delete p2; // ???
return 0;
}
我希望这表明是否可以将指针传递给void operator delete(void*) 与是否可以将同一指针用作delete 的操作数无关。
【问题讨论】:
-
仅供参考:FCD (N3092) 不再是最新草案。最新的草案是 N3225。我一直在更新c++-0x tag wiki page,并提供指向最新 PDF 草案的链接。
-
请注意,涵盖此内容的 5.3.5/2 已在最新草案中进行了修改。它现在说指针可能是“指向由先前的 new-expression 创建的非数组对象的指针”,并且 new-expression 确实包括放置 new表达式。我不认为这是故意的。
-
@James:非常感谢新草稿。而 5.3.5 正是我认为应该禁止的部分,但没有。请您看看我的回答(我正准备从新草案中提取任何更改的语言),如果您认为它与这个问题有任何关系,请告诉我?
-
@James:关于 C++0x 的精彩页面,感谢最新草稿,我无权编辑它(没有青铜 C++0x 徽章:p),你认为您可以添加 Clang C++0x 状态。实施才真正开始(他们直到现在都专注于 C++03 合规性),但已经实施了一些功能。这是链接:clang.llvm.org/cxx_status.html
-
@James,您能否将您的评论放入答案中以便我接受?
标签: c++ language-lawyer delete-operator placement-new