gpt4 book ai didi

c++ - 链接静态库时静态对象的初始化

转载 作者:可可西里 更新时间:2023-11-01 18:37:14 24 4
gpt4 key购买 nike

在另一个共享库中声明的静态对象的初始化规则是什么?例如,请考虑以下内容:

文件 X.hpp:

struct X {
X ();
static X const s_x;
};

struct Y {
Y (X const &) {}
};

文件 X.cpp:

#include "X.hpp"
#include <iostream>

X::X ()
{
std::cout << "side effect";
}

X const X::s_x;

我在静态库 libX.a 中编译了 X.cpp,并尝试链接以下可执行文件(文件 main.cpp):

#include "X.hpp"

int main ()
{
(void)X::s_x; // (1)
X x = s_x; // (2)
Y y = s_x; // (3)
}

只有 (1) 或 (2),什么也不会发生。但是如果我添加(3),静态对象被初始化(即打印“副作用”)。 (我使用 gcc 4.6.1)。

有没有办法预测这里会发生什么?

我不明白指令 (2) 为何不强制 X::s_x 对象默认构造,而 (3) 却强制构造。

编辑:构建命令:

g++ -c X.cpp
g++ -c main.cpp
ar rcs libX.a X.o
g++ -o test main.o -L. -lX

最佳答案

默认情况下,在许多平台上,如果您的程序没有引用静态库中给定目标文件中的任何符号,则整个目标文件(包括静态初始值设定项)将被删除。因此链接器忽略了 libX.a 中的 X.o,因为它看起来未被使用。

这里有几个解决方案:

  1. 不要依赖静态初始化器的副作用。这是最便携/最简单的解决方案。
  2. 通过以编译器无法识别的方式引用虚拟符号(例如将地址存储到外部可见的全局变量中),在每个文件中引入一些虚假的依赖关系。
  3. 使用一些特定于平台的技巧来保留相关对象。例如,在 Linux 上,您可以使用 -Wl,-whole-archive a.o b.a -Wl,-no-whole-archive

关于c++ - 链接静态库时静态对象的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7327741/

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