Vit*_*meo 2 c++ swap undefined-behavior language-lawyer c++14
#include <iostream>
#include <type_traits>
using namespace std;
// Non-trivially-copyable type.
struct NTC
{
int x;
NTC(int mX) : x(mX) { }
~NTC() { cout << "boop." << x << endl; }
};
int main()
{
using AS = aligned_storage_t<sizeof(NTC), alignof(NTC)>;
// Create two `std::aligned_storage` instances
// and "fill" them with two "placement-new-constructed"
// `NTC` instances.
AS as1, as2;
new (&as1) NTC{2};
new (&as2) NTC{5};
// Swap the `aligned_storages`, not their contents.
std::swap(as1, as2);
// Explicitly call `~NTC()` on the contents of the
// aligned storage instances.
NTC& in1{*static_cast<NTC*>(static_cast<void*>(&as1))};
NTC& in2{*static_cast<NTC*>(static_cast<void*>(&as2))};
in1.~NTC();
in2.~NTC();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以上代码是否未定义行为?
这就是我认为发生的事情:
NTC 是一种非平凡的可复制类型. NTC对象的内存位置(std::aligned_storage).NTC实例直接构造到内存位置.std::aligned_storage实例是PODTypes.
这意味着该类型与C编程语言中使用的类型兼容,可以使用C库函数进行操作:它可以使用std :: malloc创建,可以使用std :: memmove等进行复制,并且可以进行交换直接使用C库,采用二进制形式.
NTC对象的析构函数/复制构造函数.我的任何一点都不正确吗?如果确实发生了未定义的行为,程序的哪个部分会发生?为什么?
新的可能正确/不正确的信息(从已删除的答案中收集):
std::aligned_storage 几乎只是C风格数组的typedef.std::swap自C++ 11以来,C风格的数组有一个重载.std::swap_ranges,它交换了数组中的每个元素.std::aligned_storage实例应该逐个元素地交换它们的内容.我在这些新的假设中犯了什么错误吗?
小智 5
在将非平凡可复制类型放入其中之后直接访问缓冲区的字节是一个非常糟糕的想法,但尚未定义.
交换后尝试访问缓冲区NTC违反了别名规则,[basic.lval] p10:
如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
(10.1) - 对象的动态类型,
[....]
通过memcpy或等效复制一个简单的可复制类型暗示保留动态类型.对于非平凡的可复制类型没有这样的含义,因此在交换之后,您不再有任何NTC对象可以访问.
| 归档时间: |
|
| 查看次数: |
470 次 |
| 最近记录: |