【发布时间】:2019-04-13 14:19:22
【问题描述】:
2 个打印语句打印不同的数字。据我所知,我在这里没有做任何狡猾的const_cast,所以我不确定我可能犯了什么UB。
这段代码格式正确吗?
编译器能否依赖
A::num是const的事实,因此允许打印相同的数字?
代码:
struct A
{
const int num = 100;
A() {}
A(int in) : num{in} {}
void call()
{
new (this) A{69};
}
};
int main()
{
A a;
std::cout << a.num << '\n';
a.call();
std::cout << a.num << '\n';
}
【问题讨论】:
-
我要冒昧地说,对于已经包含现有类实例的内存,
placement new几乎可以肯定是未定义的行为。您可能会侥幸逃脱(尽管我假设编译器会警告您),因为不涉及内存分配或虚函数,但这似乎是最狡猾的想法。 -
[basic.life] "在具有静态、线程或自动存储持续时间的 const 完整对象所占用的存储空间内,或在这样的存储空间内创建一个新对象用于在其生命周期结束之前占用的 const 对象,会导致未定义的行为。"
-
@ShadowRanger 信不信由你,您可以重复使用活动对象的存储空间! [basic.life] "程序可以通过重用对象占用的存储空间或通过显式调用具有非平凡析构函数的对象的析构函数来结束对象的生命周期。对于具有非平凡析构函数的类类型,程序不需要在对象占用的存储被重用或释放之前显式调用析构函数..."
-
@RaymondChen 这是真的吗,即使只有成员是 const? “完整对象”在 [intro.object] 中定义为“不是任何其他对象的子对象的对象称为完整对象。”
-
@RaymondChen
a不是const,所以新的展示位置不是 UB。
标签: c++ constants language-lawyer undefined-behavior placement-new