为什么我的静态成员函数会在其他地方抑制文件级静态变量的存在?

时间:2018-06-05 12:18:23

标签: c++ static linker

我有一个类型

struct J : ::std::enable_shared_from_this<J> {
  static ::std::weak_ptr<J>& r() {
    static ::std::weak_ptr<J> _r;
    return _r;
  }
  J() {
    r() = shared_from_this();
  }
};

基本上提供了一些日志记录。但是,当我启用静态函数r()时,程序中的其他位置是一个静态变量:

// .cpp
namespace {
  llvm::cl::opt<bool> var("var");
}
从某种意义上来说,某种程度上已经被打破了。不会产生错误,因为var永远不会通过名称引用,而只是应该添加一个命令行开关(没有链接J::r的单词)。

这可能是什么原因?我试图将示例降低到最低限度,但无法生成MWE。

2 个答案:

答案 0 :(得分:1)

shared_from_this只有在this已由其他std::shared_ptr管理时才能调用。由于您是从J的构造函数调用它,我们可以检查不是这种情况。

来自shared_from_this's page on cppreference.com

  

允许仅在先前共享的对象上调用shared_from_this,即在由std::shared_ptr管理的对象上。否则行为是未定义的(直到C ++ 17)std::bad_weak_ptrshared_ptr构造函数从默认构造的weak_this抛出(自C ++ 17起)。

从C ++ 17开始,你的代码会更清晰地破解。

代码

#include <memory>
#include <utility>

struct J : std::enable_shared_from_this<J>
{
    J() {
        std::ignore = shared_from_this();
    }
};

int main()
{
    std::ignore = std::make_shared<J>();
}

编译&amp;运行

g++ -std=c++17 -Wall -Wextra -pedantic -Werror -O3 main.cpp && ./a.out

输出

terminate called after throwing an instance of 'std::bad_weak_ptr'
  what():  bad_weak_ptr
bash: line 7: 28216 Aborted                 (core dumped) ./a.out

在C ++ 17之前,您的代码具有未定义的行为。我只能猜测这表现为随机/奇怪的行为。

我打赌你想要更简单的东西:

#include <memory>

struct J
{
    static std::weak_ptr<J> r() { return _auto_manager; }
private:
    static std::shared_ptr<J> _auto_manager;
};
std::shared_ptr<J> J::_auto_manager = std::make_shared<J>();


int main()
{
    auto p = J::r();
}

答案 1 :(得分:0)

struct J {
  static J*& r() {
    static J* _r;
    return _r;
  }
  J() {
    r() = this;
  }
};

解决了问题,因为在ctor中使用shared_from_this是错误的。但是为什么链接器只省略var还不清楚。程序应该在运行时中断,但应该编译和链接。