gpt4 book ai didi

c++ - 初始化命名空间中的 const 对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:58:05 25 4
gpt4 key购买 nike

我在初始化命名空间中的一些常量对象时遇到了问题。我有一个如下的命名空间:

namespace myNamespace{
const std::string HI = "Hi";
const std::string BYE = "Bye";

inline std::vector<std::string> createHiAndByeVector(){
std::vector<std::string> temp;
temp.push_back(HI);
temp.push_back(BYE);
return temp;
}

const std::vector<std::string> HI_AND_BYE = createHiAndByeVector();
}

如果我调试初始化,我可以看到 HIBYE 都被分配了字符串文字。执行继续到 initialziae HI_AND_BYE,但是当我们进入 createHiAndByeVector() 函数时,HIBYE 没有值(value)了。然后我在 push_back() 方法中遇到段错误。如果查看调用堆栈,我会看到以下行:__static_initialization_and_destruction_0()。到底是怎么回事?我的对象是否在构建后立即被销毁?

最佳答案

我的猜测是这里的问题违反了单一定义规则 (ODR)。这里的猜测是这段代码实际上是在一个header中,这也是你将函数声明为inline的原因。

现在,此代码在多个翻译单元(.cpp 文件)、TU1 和 TU2 中编译。这导致两组常量和内联函数。现在,在链接时,常量彼此独立存在,因为它们具有内部链接(命名空间级别的 const 导致此)。但是,该函数没有内部链接,而是指示链接器通过 inline 丢弃除一个实例之外的所有实例。现在,剩下的一个用于初始化 TU1 和 TU2 中的 vector ,但它使用其中一个的常量字符串。取决于这些未定义的初始化时间,它可以工作或不工作。这基本上就是上面 Deamonpog 提到的初始化顺序失败。

回到 ODR,问题在于内联函数被编译了两次但它们并不相同,因为它们隐式引用了不同的字符串常量。当 header 中有匿名 namespace 时,会出现类似的问题。顺便说一句:除此之外,这个问题与命名空间无关!有两种方法可以解决这个问题:

  1. 也将初始化函数设为静态。这将所有这些常数和函数与其他翻译单元中的兄弟分开。
  2. 您只需在 header 中声明 (extern string const BYE;) 常量并在单独的 TU 中实现它们 (string const BYE = "Bye!";) .这样您就只有一个实例,可以由程序的不同部分共享。

关于c++ - 初始化命名空间中的 const 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14917130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com