控制静态对象构造函数的顺序

时间:2012-03-17 06:45:45

标签: c++ constructor c++11

我正在用c ++ 11编写一个小内核,并且在创建任何其他静态对象之前必须构造两个具有相同类型的实例。

我写的代码如下:

// test.hpp
class test {
  // blahblah...
};

// test.cpp
typedef char fake_inst[sizeof(test)] __attribute__((aligned(alignof(test))));

fake_inst inst1;
fake_inst inst2;

// main.cpp
extern test inst1;
extern test inst2;

int kmain() {
    // copy data section

    // initialize bss section

    new (&inst1) test();
    new (&inst2) test();

    // call constructors in .init_array

    // kernel stuffs
}

它构建并按预期工作,没有任何警告消息,但LTO没有。

我收到大量警告信息抱怨类型匹配,我想知道是否有解决方法,因为它让我困惑,找到其他“真正的”警告或错误消息。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

C ++不提供管理跨多个文件的全局对象的初始化顺序的方法。如果你需要紧密管理这些对象的初始化顺序,那么我强烈建议你使它们成为全局对象。使它们成为包含静态对象的全局函数,并返回指向它们的指针。

但即便如此,这比完全手动初始化还要危险。只需向那些需要它们的人提供一些指针(最好不要全局),你会没事的。

答案 1 :(得分:1)

你能使用GCC的init_priority属性吗?

Some_Class  A  __attribute__ ((init_priority (2000)));
Some_Class  B  __attribute__ ((init_priority (543)));

http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#C_002b_002b-Attributes

答案 2 :(得分:0)

// in an .h file

typedef char fake_inst[sizeof(test)] __attribute__((aligned(__alignof__(test))));

extern fake_inst fake_inst1;
extern fake_inst fake_inst2;

inline test& f_inst1() { return *reinterpret_cast<test*>(fake_inst1); }
inline test& f_inst2() { return *reinterpret_cast<test*>(fake_inst2); }

// and for readability

static test& inst1 (f_inst1());
static test& inst2 (f_inst2());

希望inst1f_inst1()都会得到优化。

答案 3 :(得分:0)

也许是这样的?

// ... .h
template<typename T>
union FakeUnion {
  FakeUnion() {}
  ~FakeUnion() {}

  T inst;
};

extern FakeUnion<test> inst1_;
extern FakeUnion<test> inst2_;
static constexpr test& inst1 = inst1_.inst;
static constexpr test& inst2 = inst2_.inst;
// ... .h end

// ... .cpp
FakeUnion<test> inst1_;
FakeUnion<test> inst2_;
// ... .cpp end

main内,您可以说new (&inst1) test;。它现在不应再发出有关类型不一致违规的警告,因为与您的代码不同,此代码不包含在不同文件中具有不同类型的变量。