std :: 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;
}

gcc很高兴地通过了这个测试文件(当然,这个文件来自libstdcxx),而clang对于该VERIFY部分而言失败

题:

  1. 是实现依赖还是不确定的行为?
  2. 我猜想这个后置条件(b->a != nullptr)对于gcc很重要,否则它将没有测试文件,但我不知道它的背后是什么。与优化有关吗?我知道很多UB都是为了更好的优化。
霍尔特

clang (libc ++)在这一点上似乎不兼容,因为该标准指出:

[unique.ptr.single.dtor]

~unique_ptr();
  1. 要求:表达式get_­deleter()(get())应格式正确,行为应明确,并且不得引发异常。[ 注意:的使用default_­delete要求T为完整类型。— 尾注  ]

  2. 效果:如果get() == nullptr没有效果。否则get_­deleter()(get())

因此,析构函数应该等效于get_deleter()(get()),这意味着b->a不能nullptr在的析构函数之内Aget_deleter()delete指令内部调用)。


附带说明一下,clang(libc ++)和gcc(libstdc ++)都将nullptr销毁时的指针设置std::unique_ptr,但这是gcc析构函数:

auto& __ptr = _M_t._M_ptr();
if (__ptr != nullptr)
    get_deleter()(__ptr);
__ptr = pointer();

...这是clang(呼叫reset()):

pointer __tmp = __ptr_.first();
__ptr_.first() = pointer();
if (__tmp)
   __ptr_.second()(__tmp);

如您所见,gcc先删除然后分配给nullptrpointer()),然后clang先分配给nullptrpointer())然后删除1


1 pointer是一个对应于的别名Deleter::pointer(如果存在的话)或简称为T*

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

std :: unique_ptr析构函数构造函数顺序

std::unique_ptr 在虚拟析构函数上重置 SIGABRT

thread_local std :: unique_ptr版本未调用析构函数

如果A有析构函数,std :: unique_ptr <A>什么时候需要特殊的删除器?

std :: unique_ptr的自定义删除程序是否是手动调用析构函数的有效位置?

如何允许 std::unique_ptr 访问类的私有析构函数或使用私有析构函数实现 C++ 工厂类?

C ++-vector <>中的std :: unique_ptr为nullptr

使用std :: map时,包含unique_ptr的结构中的默认析构函数会导致编译错误

具有显式析构函数和std :: unique_ptr <>成员的类不能在std :: vector <>中使用吗?

为什么要为具有非平凡析构函数的类声明constrexpr构造函数(例如unique_ptr,std :: variant)

std :: unique_ptr constexpr构造函数

std :: unique_ptr构造函数的行为

std :: list的擦除成员函数是否为所有存储的元素调用析构函数?

查看std :: unique_ptr及其nullptr_t构造函数

使用std :: move(nullptr)的unique_ptr的operator =的C ++错误

如何检查std :: unique_ptr是否为空(如果它位于std :: vector中)?

std :: unique_ptr :: release()与std :: move()

std :: unique_ptr与std :: map

是否可以使用fill构造函数创建std :: vector <std :: unique_ptr <Bar >>?

std :: remove_if是否调用析构函数?

奇怪的错误:当未真正创建指针时,使用删除的函数'std :: unique_ptr <_Tp,_Dp> :: unique_ptr

参数std :: unique_ptr <T> &&的std :: move或std :: forward

将std :: unique_ptr重置为数组指针有什么问题?

从本地原始指针初始化 std::unique_ptr 是否安全?

std :: move是否会使原始指针指向unique_ptr所拥有的东西无效?

为什么std :: unique_ptr构造函数接受外部指针

为什么std :: unique_ptr构造函数接受外部指针?

更改std :: unique_ptr中的指针而不破坏它

交换指针:相当于`std :: unique_ptr :: swap`