如果我的库foo中有一些静态初始化代码,并且链接情况如下:
executable -> libShared.so (dynamic linking)
executable -> libFoo.a (static linking)
libShared.so -> libFoo.a (static linking)
这是否导致静态初始化代码运行两次 - 如果它有副作用,可能会做两个不同的可见事情?
libShared.so只通过导出自己的符号,而不是导出任何libFoo.a来做正确的事情。但是在这个过程中有两个libFoo.a副本,实际上是彼此远离命名空间。我的理解是正确的 - 初始化步骤会有重复吗?
(当然正确的方法是让libFoo.a不做任何事情,比如在静态初始化器中创建可见的副作用,但让我们假设船已经航行......)。
答案 0 :(得分:2)
是的,构造函数将运行两次。构建可执行文件或共享库时,会创建一个辅助方法,它枚举要构造的所有全局变量并调用它们的初始值设定项(ISO C ++允许使用其他方法,但不能用于具有共享库的系统)。加载可执行文件和共享库时会调用这些帮助程序。
现在你碰巧有两个这样的方法初始化两个不同的内存部分。这会创建两个对象,它们的地址会有所不同。
如果可执行文件只有extern
全局声明,但显然它不能 - 它会使用相同的静态库,这会有所不同。
PS。全局对象的析构函数有自己的辅助方法,工作方式大致相同。
答案 1 :(得分:0)
静态库只是目标文件的连接 - 除非您明确提供此类代码,否则它们中没有代码来运行静态对象的构造函数。因此,静态库中的静态对象不会运行构造函数两次,甚至可能运行一次。此外,由于大多数链接器搜索静态库的方式,多次链接它们是一种非常常见的做法。