c语言 gcc 构造函数,关于c ++:在对象构造函数之前调用GCC __attribute __((constructor))...

在我的共享库中,我需要将一些数据加载到unordered_map中,然后尝试在标记为__ attribute __((constructor))的函数中进行操作。 但是我在每个地图操作上都得到了SIGFPE。 在研究了stackoverflow之后,我发现这意味着unordered_map未初始化。 这对我来说是完全出乎意料且难以理解的,因为乍一看它违反了C ++合同。 任何人都可以帮助我在构造函数运行后如何运行此方法? 这是一个带有我自己的构造函数的工作示例,该示例表明未调用它:

#include

class Ala {

int i;

public:

Ala() {

printf("constructor called

");

i = 3;

}

int getI() {

return i;

}

};

Ala a;

__attribute__((constructor))

static void initialize_shared_library() {

printf("initializing shared library

");

printf("a.i=%d

", a.getI());

printf("end of initialization of the shared library

");

}

结果是

initializing shared library

a.i=0

end of initialization of the shared library

constructor called

但是,如果尝试使用std :: cout而不是printfs,它将立即进入SEGFAULTs(因为未运行流的构造函数)

您可以尝试使用__attribute __((init_priority(123))语法,并为a赋予比该函数小的数字

您需要指定优先级以确保构造函数的正确顺序。 最好远离编译器扩展,并按照答案中的建议使用香草c ++构造。

"它违反了C ++合同":当然,它违反了C ++合同; 您使用了编译器扩展-这意味着它的行为不会像标准C ++。 您需要阅读扩展的文档以了解其行为。

不幸的是,@ MartinBonner的文档似乎还不错,它不涉及诸如与没有该属性的全局对象交互之类的事情。

我认为这里发生的顺序是不确定的。 它当然似乎没有文件记录。 它是一个旧线程,但请参阅:stackoverflow.com/questions/8433484/

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

修复它的方法是使用另一个普通的C ++构造,例如一个全局对象,通过在与另一个全局对象相同的TU中定义它,可以正确初始化初始化的顺序:

Ala a;

static void initialize_shared_library() {

printf("initializing shared library

");

printf("a.i=%d

", a.getI());

printf("end of initialization of the shared library

");

}

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

可以将其表示为static struct init { init() { * do init * } } force_init;-避免使用有点棘手的逗号运算符。

如果使用返回静态局部变量的函数,则该变量将在首次调用该函数时进行初始化。

请参阅:什么时候分配/初始化函数级静态变量?

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

");

printf("a.i=%d

", a.getI());

printf("end of initialization of the shared library

");

}

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

如果您只想在初始化a之后运行某些程序,可以通过多种方法来完成,而无需离开Standard C ++。这是一个:

struct Ala2 : Ala

{

Ala2()

{

// your init code here

}

};

Ala2 a;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值