C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 静态变量初始化两次大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
虑到我在编译单元中有一个静态变量,最后在静态库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 <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

有人可以解释这里发生了什么吗?什么是链接器?同一个变量如何初始化两次?

@L_618_41@

您将libA.a包含到libB.so中.通过这样做,libB.so和libA.a都包含ClassA.o,它定义了静态成员.

在您指定的链接顺序中,链接器从静态库libA.a中引用ClassA.o,因此ClassA.o初始化代码在main()之前运行.当访问动态libB.so中的第一个函数时,将运行libB.so的所有初始化程序.由于libB.so包含ClassA.o,所以ClassA.o的静态初始化程序必须运行(再次).

可能的修复:

>不要将ClassA.o放在libA.a和libB.so中.

g++ -shared -o libB.so ClassB.o

>不要使用这两个库;不需要libA.a

g++ -o test Test.cpp libB.so

应用上述任一修复问题:

ClassA::ClassA() this=0x600e58
main()
ClassA::test() this=0x600e58
ClassB::ClassB() this=0x7fff1a69f0cf
ClassB::test() this=0x7fff1a69f0cf
ClassB::test: call staticA.test()
ClassA::test() this=0x600e58
main: END
ClassB::~ClassB() this=0x7fff1a69f0cf
ClassA::~ClassA() this=0x600e58

大佬总结

以上是大佬教程为你收集整理的c – 静态变量初始化两次全部内容,希望文章能够帮你解决c – 静态变量初始化两次所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。