Talk:More C++ Idioms/Nifty Counter

Static Object Within the Header
Doesn't the definition of initializer (in the header file) need to be static or in an anonymous namespace? Otherwise, wouldn't the linker complain that it is multiply defined? (comment from SCFrench from 18 October, 2015)


 * As SCFrench correctly pointed out, the initializer object within the header must be static. Otherwise one will get a multiple definition error at link time. Static is necessary, since every translation unit needs its own initializer.
 * However, the code in the article still misses one very important point: how to store the global Stream object?
 * Just check the following example
 * First the header


 * Now the implementation file


 * Finally another translation unit


 * The global Stream object is defined as extern in every translation unit - or, to be more precise, a reference to it.
 * The storage for this object is then defined within one translation unit - Stream.cpp - as an aligned_storage of size sizeof(Stream).
 * The reference to the global Stream object is placed in this storage and the initializer's constructor and destructor run the Stream's constructor and destructor.


 * Why this buffer stuff?
 * Because this is the only way to guarantee, that stream's destructor is not executed, until the last initializer's destructor is executed.
 * Writing just "Stream stream" within Stream.cpp creates a variable whose constructor is run after the initializer's constructor and whose destructor is run before (!) the initializer's destructor.
 * This is because, the static initializer is defined within the header Stream.h and thus before the Stream variable within Stream.cpp. Thus the initialization order is implementation defined.
 * The aligned_storage approach above is well-defined by the standard (note that one needs C++11).
 * I will wait until tomorrow noon for replies and then change the article.
 * --2001:4CA0:2002:0:B596:51BD:D5B7:1CB (discuss) 17:01, 2 January 2016 (UTC)
 * --2001:4CA0:2002:0:B596:51BD:D5B7:1CB (discuss) 17:01, 2 January 2016 (UTC)


 * I have now rewritten the book to present code that works.
 * Note, that the last checked version was wrong, and that all former versions did not even mention how to store the Stream object.
 * This, however, is very important when it comes to the order in which constructors and destructors are called.
 * --2003:63:A76:8660:E84B:5855:8B39:2787 (discuss) 12:44, 3 January 2016 (UTC)

Two remarks
--2001:16B8:42F2:200:184C:E235:96C6:9A1E (discuss) 09:11, 16 November 2020 (UTC)
 * The whole stream_buf / align / placement new stuff won't be necessary if you use a pointer and plain new instead of a reference, no?
 * The whole idiom won't work when stream.h is included in a pre-compiled header! Doesn't matter if directly or somewhere deep in the include chain, the initializer will not be constructed first. At least not with Visual Studio 2019.