을 고려하십시오. 정적 변수 라이브러리 libA로 끝나는 컴파일 유닛에 정적 변수가 있습니다. 그런 다음이 변수에 액세스하는 다른 컴파일 단위가 libB.so 라이브러리 (libA는 libB에 링크되어야 함)로 공유됩니다. 마지막으로 나는 또한 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 <cstdio>
#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 <cstdio>
#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 <cstdio>
#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
는 누군가에 무슨 일이 일어나고 있는지 설명해 주시겠습니까 이리? 링커는 무엇을하고 있습니까? 동일한 변수를 어떻게 두 번 초기화 할 수 있습니까?
관련 (아마도 중복) : http://stackoverflow.com/questions/6714046/c-linux-double-destruction -of-static-variable-linking-symbols-overlap – jogojapan
정적 라이브러리를 컴파일하고 공유 라이브러리를 컴파일하는 것과 관련 될 수 있습니까? 그래서 libB.so에 ClassA.o와 ClassB.o의 초기화 코드가 있습니까? – heksesang
@heksesang : 예,이 별자리에서만 발생합니다. 만약 내가'A'와'B' 정적 라이브러리 또는 둘다 공유 라이브러리를 만들면, 나는이 문제에 직면하지 않는다 ('A'의 c'or는 한 번만 실행된다). 그러나 필자는 링커가 중복 된 기호 및 init 호출을 인식하고 제거 할 것으로 기대합니다. 내 가정이 잘못 되었습니까, 아니면 링커입니까? – bselu