Nifty/Schwarz counter, standard compliant?

后端 未结 2 1568
南笙
南笙 2020-12-15 06:31

I had a discussion this morning with a colleague about static variable initialization order. He mentioned the Nifty/Schwarz counter and I\'m (sort of) puzzled. I understan

2条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-15 07:28

    I think missing from this example is how the construction of Stream is avoided, this often is non-portable. Besides the nifty counter the initialisers role is to construct something like:

    extern Stream in;
    

    Where one compilation unit has the memory associated with that object, whether there is some special constructor before the in-place new operator is used, or in the cases I've seen the memory is allocated in another way to avoid any conflicts. It seems to me that is there is a no-op constructor on this stream then the ordering of whether the initialiser is called first or the no-op constructor is not defined.

    To allocate an area of bytes is often non-portable for example for gnu iostream the space for cin is defined as:

    typedef char fake_istream[sizeof(istream)] __attribute__ ((aligned(__alignof__(istream))))
    ...
    fake_istream cin;
    

    llvm uses:

    _ALIGNAS_TYPE (__stdinbuf ) static char __cin [sizeof(__stdinbuf )];
    

    Both make certain assumption about the space needed for the object. Where the Schwarz Counter initialises with a placement new:

    new (&cin) istream(&buf)
    

    Practically this doesn't look that portable.

    I've noticed that some compilers like gnu, microsoft and AIX do have compiler extensions to influence static initialiser order:

    • For Gnu this is: Enable the init-priority with the -f flag and use __attribute__ ((init_priority (n))).
    • On windows with a microsoft compiler there is a #pragma (http://support.microsoft.com/kb/104248)

提交回复
热议问题