静态库的全局变量的静态初始化和销毁??不会在 g++ 中发生

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

Until some time ago, I thought a .a static library was just a collection of .o object files, just archiving them and not making them handled differently. But linking with a .o object and linking with a .a static library containing this .o object are apparently not the same. And I don't understand why...

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

Let's consider the following source code files:

// 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;

让我们编译并链接并运行这段代码:

Let's compile and link and run this code:

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

调用全局gObject对象的构造函数和析构函数.

The constructor an the destructor of the global gObject object is called.

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

Now let's create a static library from our code and use (link) it in another program:

g++ -Wall -c object.cpp main.cpp
ar rcs lib.a object.o
g++ -Wall -o main2 main.o lib.a
./main2
> main

  • gObject的构造函数和析构函数没有被调用...为什么?
  • 如何自动调用它们?
  • 谢谢.

    推荐答案

    .a 静态库包含多个 .o 但除非您从主应用程序.
    .o 文件独立链接始终.

    .a static libraries contain several .o but they are not linked in unless you reference them from the main app.
    .o files standalone link always.

    所以链接器中的 .o 文件总是进入内部,无论是否引用,但从 .a 文件中只引用 .o 目标文件已链接.

    So .o files in the linker always go inside, referenced or not, but from .a files only referenced .o object files are linked.

    请注意,静态全局对象在您实际引用编译单元中的任何内容之前不需要初始化,大多数编译器会在 main 之前初始化它们,但唯一的要求是它们在任何函数之前初始化编译单元被执行.

    As a note, static global objects are not required to be initialized till you actually reference anything in the compilation unit, most compilers will initialize all of them before main, but the only requirement is that they get initialized before any function of the compilation unit gets executed.

相关文章