Managing the constructor order of static objects

I am writing a tiny kernel with C ++ 11 and have two instances of the same type that must be created before any other static objects are created.

The code I wrote is as follows:

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

It builds and works as expected without warning messages, but not with LTO.

I get a ton of warning messages complaining about type matching, and I'm wondering if there is a workaround, as this confuses me to find other “real” warnings or error messages.

Any suggestion?

+6
source share
4 answers

Maybe so?

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

Inside main you can say new (&inst1) test; . Now it should not give warnings about violations of type mismatch, because unlike your code, this code does not contain variables that have different types in different files.

0
source

C ++ does not offer you ways to control the initialization order for global objects in multiple files. If you need to strictly control the initialization order of these objects, I highly recommend that you not create their global objects. Make them global functions that contain static objects and back pointers to them.

But even then, which is less dangerous than full manual initialization. Just make a few pointers to the objects that are available to those who need them (preferably not around the world), and everything will be in order.

+2
source

Can't use the GCC attribute 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

+1
source
 // 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()); 

We hope that both inst1 and f_inst1() will be optimized.

0
source

Source: https://habr.com/ru/post/910970/


All Articles