__attribute__((constructor)) call order confusion

前端 未结 4 1003
伪装坚强ぢ
伪装坚强ぢ 2021-02-06 02:55

The answer here demonstrates that __attribute__((constructor)) is not called after static initialization, it is called in the declaration order.

Then, w

相关标签:
4条回答
  • 2021-02-06 03:16

    See this: http://gcc.gnu.org/ml/gcc-help/2011-05/msg00220.html and the answer http://gcc.gnu.org/ml/gcc-help/2011-05/msg00221.html

    In particular quoting from the answer:

    All objects with an init_priority attribute are constructed before any object with no init_priority attribute.

    Note it is actually about __attribute__((init_priority)) and not about __attribute__((constructor)) but I believe they both actually use the same code in gcc, respectively in gnu linker. First just corresponds to C++ objects, i.e. calling their constructor/destructor, the latter is about marking specific functions as constructor or destructor.

    IMHO, the __attribute__((constructor)) exists mainly because of C, not C++.

    0 讨论(0)
  • 2021-02-06 03:23

    the biggest advantage of attribute((constructor))__ is the priority associated with each block and specifically helps your case.

    You have two block of codes which have data hazard (one set should be executed first). This cannot be achieved by single static block. Using one static block and one attribute((constructor))__ will not solve your problem because of confusion regarding the order.

    The best way to deal with the problem is to have two attribute((constructor))__ with two different priorities. Move your existing static initialization block to higher priority (0) and the other code block to lower priority.

    0 讨论(0)
  • 2021-02-06 03:29

    You might try using linker scripts for ld. You can read more about it here, but I guess what you are looking for is

    .ctors : { *(SORT(.ctors)) MyLastInitChance.o(SORT(.ctors)) }
    .dtors : { *(SORT(.dtors)) MyLastInitChance.o(SORT(.dtors)) }
    

    in SECTIONS{...} block. That should rearrange .ctors sections so file provided will call it's constructors as the last one. Obviously more advanced solutions are also available if you find yorself in need for one;)

    HINT: writing your own link-script is tedious. Use ld's --verbose option that prints out used link script and modify it. Then add your linking script using -T switch.

    0 讨论(0)
  • 2021-02-06 03:35

    Can you implement a "construct on first use" pattern for this global?

    e.g.

    Magic& gMagic()
    {
        static Magic magic;
        return magic;
    }
    

    It will get built after all regular static ctors, but before any regular code needs it.

    0 讨论(0)
提交回复
热议问题