繁体   English   中英

GCC __attribute __((构造函数))在对象构造函数之前调用

[英]GCC __attribute__((constructor)) is called before object constructor

在我的共享库中,我需要将一些数据加载到unordered_map中,并尝试在标记为__ attribute __((构造函数)的函数中执行此操作。 但是我在每个地图操作上都获得了SIGFPE。 在查看stackoverflow之后,我发现这意味着unordered_map未初始化。 这对我来说是非常意外和不可理解的,因为它一眼就违反了C ++合同。 任何人都可以帮助我在运行构造函数后如何运行此方法? 这是一个使用我自己的构造函数的工作示例,它表明它没有被调用:

#include <stdio.h>

class Ala {
    int i;
public:
    Ala() {
        printf("constructor called\n");
        i = 3;
    }

    int getI() {
        return i;
    }
};

Ala a;

__attribute__((constructor))
static void initialize_shared_library() {
    printf("initializing shared library\n");
    printf("a.i=%d\n", a.getI());
    printf("end of initialization of the shared library\n");
}

结果是

initializing shared library
a.i=0
end of initialization of the shared library
constructor called

但是如果有人试图使用std :: cout而不是printfs,那么它会立即进入SEGFAULTs(因为没有运行流的构造函数)

__attribute__((constructor))是一个编译器扩展,因此你离开了标准C ++的领域。 看起来GCC的构造函数在全局初始化之前运行。

修复它的方法是使用另一个vanilla C ++构造,例如一个全局对象,通过在与其他全局相同的TU中定义它来正确地对其进行排序:

Ala a;

static void initialize_shared_library() {
    printf("initializing shared library\n");
    printf("a.i=%d\n", a.getI());
    printf("end of initialization of the shared library\n");
}

static int const do_init = (initialize_shared_library(), 0);

如果使用返回静态局部变量的函数,则在第一次调用函数时将初始化变量。 请参阅: 何时分配/初始化函数级静态变量?

struct Ala {
   // Your code here
   static Ala& get_singleton();
};

Ala& Ala::get_singleton() {
   static Ala singleton;
   return singleton;
}

static void initialize_shared_library() {
    Ala& a = get_singleton();
    printf("initializing shared library\n");
    printf("a.i=%d\n", a.getI());
    printf("end of initialization of the shared library\n");
}

正如其他人所说,通常最好将所有初始化过程封装在一个对象中,让构造函数为你完成工作(构造函数的主体在初始化类的所有成员之后执行)。

如果你只是想运行的东西后a初始化有几种方法可以做到不留标准C ++; 这是一个:

struct Ala2 : Ala
{
    Ala2()
    {
         // your init code here
    }
};

Ala2 a;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM