使用g ++不会发生静态初始化和破坏静态库的全局变量

时间:2009-11-26 16:23:59

标签: c++ g++ linker global-variables static-libraries

直到一段时间以前,我认为.a静态库只是.o对象文件的集合,只是归档它们而不是以不同方式处理它们。但与.o对象链接并与包含此.o对象的.a静态库链接显然不一样。我不明白为什么......

让我们考虑以下源代码文件:

// main.cpp
#include <iostream>
int main(int argc, char* argv[]) {
    std::cout << "main" << std::endl;
}

// object.hpp
#include <iostream>
struct Object
{
    Object() { std::cout << "Object constructor called" << std::endl; }
    ~Object() { std::cout << "Object destructor called" << std::endl; }
};

// object.cpp
#include "object.hpp"
static Object gObject;

让我们编译并链接并运行以下代码:

g++ -Wall object.cpp main.cpp -o main1
./main1
> Object constructor called
> main
> Object destructor called

构造函数是全局gObject对象的析构函数。

现在让我们从代码中创建一个静态库,并在另一个程序中使用(链接)它:

g++ -Wall -c object.cpp main.cpp
ar rcs lib.a object.o
g++ -Wall -o main2 main.o lib.a
./main2
> main
  • gObject的构造函数和析构函数未被调用...为什么?
  • 如何自动调用它们?

感谢。

1 个答案:

答案 0 :(得分:30)

.a静态库包含多个.o,但除非您从主应用中引用它们,否则它们不会链接。
.o文件始终是独立链接。

所以链接器中的.o文件总是在里面,引用或不引用,但是来自.a文件只引用了.o目标文件。

作为一个注释,静态全局对象不需要初始化,直到您实际引用编译单元中的任何内容,大多数编译器将在main之前初始化所有这些对象,但唯一的要求是它们在任何函数之前被初始化。编译单元被执行。