考虑到我在编译单元中有一个静态变量,最后在静态库libA中.然后我有另一个编译单元访问这个变量,最终在一个共享库libB.so(所以libA必须链接到libB).最后,我有一个主要功能也直接从A访问静态变量,并具有对libB的依赖(所以我链接到libA和libB).
我然后观察,静态变量被初始化了两次,即它的构造函数运行两次!这似乎不对.链接器不应该识别两个变量是否相同,并将它们优化为一个?
为了使我的困惑完美,我看到它运行两次与同一个地址!那么也许连接器确实识别了它,但是没有删除static_initialization_and_destruction代码中的第二个调用?
这是一个展示:
ClassA.hpp:
#ifndef CLASSA_HPP
#define CLASSA_HPP
class ClassA
{
public:
ClassA();
~ClassA();
static ClassA staticA;
void test();
};
#endif // CLASSA_HPP
ClassA.cpp:
#include
#include "ClassA.hpp"
ClassA ClassA::staticA;
ClassA::ClassA()
{
printf("ClassA::ClassA() this=%p\n",this);
}
ClassA::~ClassA()
{
printf("ClassA::~ClassA() this=%p\n",this);
}
void ClassA::test()
{
printf("ClassA::test() this=%p\n",this);
}
ClassB.hpp:
#ifndef CLASSB_HPP
#define CLASSB_HPP
class ClassB
{
public:
ClassB();
~ClassB();
void test();
};
#endif // CLASSB_HPP
ClassB.cpp:
#include
#include "ClassA.hpp"
#include "ClassB.hpp"
ClassB::ClassB()
{
printf("ClassB::ClassB() this=%p\n",this);
}
ClassB::~ClassB()
{
printf("ClassB::~ClassB() this=%p\n",this);
}
void ClassB::test()
{
printf("ClassB::test() this=%p\n",this);
printf("ClassB::test: call staticA.test()\n");
ClassA::staticA.test();
}
TEST.CPP:
#include
#include "ClassA.hpp"
#include "ClassB.hpp"
int main(int argc,char * argv[])
{
printf("main()\n");
ClassA::staticA.test();
ClassB b;
b.test();
printf("main: END\n");
return 0;
}
然后我编译并链接如下:
g++ -c ClassA.cpp
ar rvs libA.a ClassA.o
g++ -c ClassB.cpp
g++ -shared -o libB.so ClassB.o libA.a
g++ -c Test.cpp
g++ -o test Test.cpp libA.a libB.so
输出为:
ClassA::ClassA() this=0x804a040
ClassA::ClassA() this=0x804a040
main()
ClassA::test() this=0x804a040
ClassB::ClassB() this=0xbfcb064f
ClassB::test() this=0xbfcb064f
ClassB::test: call staticA.test()
ClassA::test() this=0x804a040
main: END
ClassB::~ClassB() this=0xbfcb064f
ClassA::~ClassA() this=0x804a040
ClassA::~ClassA() this=0x804a040
有人可以解释这里发生了什么吗?什么是链接器?同一个变量如何初始化两次?