加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – clang – shared_ptr无法运行其删除器

发布时间:2020-12-16 10:15:00 所属栏目:百科 来源:网络整理
导读:当使用clang -std = c 11构建时,此代码打印0(没有优化)或666(启用优化)(-O3产生666,这是我所期望的).当lambda通过通用引用传递时,问题就消失了. 仅供参考,GCC在我测试的所有版本上打印666. 它是编译器错误还是代码不正确? #include memory#include iostream
当使用clang -std = c 11构建时,此代码打印0(没有优化)或666(启用优化)(-O3产生666,这是我所期望的).当lambda通过通用引用传递时,问题就消失了.

仅供参考,GCC在我测试的所有版本上打印666.

它是编译器错误还是代码不正确?

#include <memory>
#include <iostream>

template <typename T>
std::shared_ptr<void> onScopeExit(T f)
{
    return std::shared_ptr<void>((void*)1,[&](void *) {
        f();
    });
}

struct A {
  void f() {
    auto scopeGuard = onScopeExit([&]() { i = 666; }); //  [1]
    // ... (some work)
  } // (lambda [1] being ? called on scope exit)

  int i = 0;
};

A a;

int main() {
  a.f();
  std::cout << a.i << std::endl;
}

有问题的编译器是:

Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0

解决方法

您的代码具有未定义的行为.你在onScopeExit中通过引用捕获f但是一旦从函数返回shared_ptr,删除器现在持有对f的悬空引用,因为f超出了范围.您需要做的是按值捕获f,然后您将没有悬空参考

template <typename T>
std::shared_ptr<void> onScopeExit(T f)
{
    return std::shared_ptr<void>((void*)1,[=](void *) {
        f();
    });
}

struct A {
  void f() {
    auto scopeGuard = onScopeExit([&]() { i = 666; }); //  [1]
    // ... (some work)
  } // (lambda [1] being ? called on scope exit)

  int i = 0;
};

A a;

int main() {
  a.f();
  std::cout << a.i << std::endl;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读