【发布时间】:2018-10-18 09:06:05
【问题描述】:
在 cmets 和这个问题的答案中:
Virtual function compiler optimization c++
有人认为循环中的虚函数调用不能被去虚拟化,因为虚函数可能会使用placement new 将this 替换为另一个对象,例如:
void A::foo() { // virtual
static_assert(sizeof(A) == sizeof(Derived));
new(this) Derived;
}
示例来自LLVM blog article about devirtualization
现在我的问题是:标准是否允许这样做?
我可以在 cppreference 上找到有关存储重用的信息:(强调我的)
如果对象是可简单破坏的或程序不依赖于析构函数的副作用,则程序不需要调用对象的析构函数来结束其生命周期。然而,如果一个程序结束了一个重要对象的生命周期,它必须确保在调用析构函数之前就地构造相同类型的新对象(例如通过placement new)隐含的
如果新对象必须具有相同的类型,则它必须具有相同的虚函数。所以不可能有不同的虚函数,因此去虚化是可以接受的。
还是我误解了什么?
【问题讨论】:
-
无论其合法性如何,我都不担心会在运行时秘密更改对象类型的不正当代码。 C++ 标准包含一个使用placement new 替换现有对象的示例是一个大错误,因为它鼓励人们认为这样做实际上是有意义的。
-
如果他们是
covariant似乎很好
标签: c++ language-lawyer