मान लें कि मेरे पास एक संकलन इकाई में स्थिर चर है जो स्थिर लाइब्रेरी libA में समाप्त होता है। इसके बाद मेरे पास इस चर का उपयोग करने वाली एक और संकलन इकाई है जो में लाइब्रेरी libB.so में समाप्त होती है (इसलिए libA libB में लिंक होना चाहिए)। आखिरकार मेरे पास मुख्य कार्य भी ए 0 से सीधे और से स्थिर वैरिएबल तक पहुंच रहा है, जिसमें libB की निर्भरता है (इसलिए मैं libA और libB के खिलाफ लिंक करता हूं)।स्टेटिक वैरिएबल दो बार शुरू किया गया है
मैं तब निरीक्षण करता हूं कि स्थैतिक चर दो बार शुरू होता है, यानी इसका कन्स्ट्रक्टर दो बार चलाया जाता है! यह सही प्रतीत नहीं होता है। क्या लिंकर दोनों वैरिएबल को समान नहीं मानना चाहिए और उन्हें एक के रूप में अनुकूलित करना चाहिए?
मेरा भ्रम सही करने के लिए, मुझे लगता है कि यह एक ही पते के साथ दो बार चलाया जाता है! तो हो सकता है कि लिंकर इसे पहचानें, लेकिन static_initialization_and_destruction code में दूसरी कॉल को हटा दें?
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
क्या यह एक स्थिर lib को संकलित करने और उसके बाद साझा lib को संकलित करने के लिए उपयोग किया जा सकता है? ताकि libB.so में ClassA.o और ClassB.o दोनों से init कोड है? – heksesang
@heksesang: हाँ, यह केवल इस नक्षत्र में होता है। अगर मैं 'ए' और' बी 'स्थिर libs या दोनों साझा libs दोनों बनाता हूं, तो मुझे इस मुद्दे का सामना नहीं करना पड़ता है ('ए' का coror केवल एक बार चलाया जाता है)। हालांकि, मैं लिंकर को डुप्लिकेट प्रतीकों और इनिट कॉल को पहचानने और खत्म करने की अपेक्षा करता हूं। क्या मेरी धारणा गलत है या क्या यह लिंकर है? – bselu