陳 力*_*陳 力 4 c++ unique-ptr nullptr
当实现我自己的unique_ptr(只是为了好玩),我发现它无法通过这个测试文件来自libstdcxx:
struct A;
struct B
{
std::unique_ptr<A> a;
};
struct A
{
B* b;
~A() { VERIFY(b->a != nullptr); }
};
void test01()
{
B b;
b.a.reset(new A);
b.a->b = &b;
}
Run Code Online (Sandbox Code Playgroud)
gcc愉快地传递了这个测试文件(当然,这个文件是来自libstdcxx),而clang因为VERIFY部分失败了.
题:
b->a != nullptr)对于gcc很重要,否则它没有测试文件,但我不知道它背后是什么.它与优化有关吗?我知道很多UB都是为了更好的优化.clang (libc ++)似乎在这一点上是不合规的,因为标准说:
Run Code Online (Sandbox Code Playgroud)~unique_ptr();
要求:表达式
get_deleter()(get())应格式良好,具有明确定义的行为,不得抛出异常.[ 注意:使用default_delete要求T是完整的类型.- 结束说明 ]效果:如果
get() == nullptr没有效果.否则get_deleter()(get()).
所以析构函数应该等价get_deleter()(get()),这意味着它b->a不能nullptr在析构函数中A(get_deleter()由delete指令调用内部).
在旁注中,clang(libc ++)和gcc(libstdc ++)都将指针设置为nullptr在销毁a时std::unique_ptr,但这里是gcc析构函数:
auto& __ptr = _M_t._M_ptr();
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
Run Code Online (Sandbox Code Playgroud)
......这里是clang(致电reset()):
pointer __tmp = __ptr_.first();
__ptr_.first() = pointer();
if (__tmp)
__ptr_.second()(__tmp);
Run Code Online (Sandbox Code Playgroud)
如您所见,gcc首先删除然后分配给nullptr(pointer()),同时clang首先分配给nullptr(pointer())然后删除1.
1 pointer是对应于Deleter::pointer(如果存在)或简单的别名T*.
| 归档时间: |
|
| 查看次数: |
329 次 |
| 最近记录: |