相关疑难解决方法(0)

静态变量初始化两次

考虑我在编译单元中有一个静态变量,它最终存在于静态库libA中.然后我有另一个编译单元访问这个变量,最终在一个共享库libB.so(所以libA必须链接到libB).最后我有一个main函数也直接从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
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

ClassB.hpp:

#ifndef CLASSB_HPP
#define CLASSB_HPP

class ClassB
{
public:
    ClassB();
    ~ClassB();

    void test();
};

#endif // CLASSB_HPP
Run Code Online (Sandbox Code Playgroud)

ClassB.cpp: …

c++ linker initialization static-members

11
推荐指数
2
解决办法
2805
查看次数

C全局静态变量初始化是由链接器完成的吗?

假设我们有:

在f1.c

#include <stdio.h>
static int x = 10;

void f1() {
  printf("f1.c : %d\n", x);
}
Run Code Online (Sandbox Code Playgroud)

main.c中

extern void f1();
int main(int argc, char **argv) {
  f1();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我们将编译和读取两个ELF文件符号表(rel.ELF和exec ELF):

$> gcc -c *.c
$> readelf -s f1.o | grep x
      Num:    Value          Size Type    Bind   Vis      Ndx Name
        5: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    3 x
$> gcc *.o
$> readelf -s a.out | grep x
      Num:    Value          Size Type    Bind   Vis      Ndx Name
       38: 0000000000601038 …
Run Code Online (Sandbox Code Playgroud)

c linker gcc symbol-table

0
推荐指数
1
解决办法
800
查看次数

标签 统计

linker ×2

c ×1

c++ ×1

gcc ×1

initialization ×1

static-members ×1

symbol-table ×1