2

In libstdc++, <iostream> header defines an instance of ios_base::Init, whose constructor atomicly increase a counter and initialize cin/cout/cerr if the counter is 0. This guarantees that cin/cout/cerr is always initialized after #include <iostream>, in every TU.

I want to implement an initializer with same behavior as ios_base::Init, i.e. I want to guarantee some of my global objects is initialized as soon as I include some header, before it gets used in constructor of another global variable. However, this needs to use atomic operation. libstdc++ uses GCC's extension, which is not standard: http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/src/c%2B%2B98/ios_init.cc?view=markup

According to How to use std::atomic efficiently, std::atomic is the only standard way to do atomic operation, so I need to a global atomic variable constructed before the initializer in all TU. To initialize it, I need another initializer that initialize it, and so on so forth, sadly, go to some infinite recursion.

So my question is, what is the best, standard way to do it?

Community
  • 1
  • 1
Kan Li
  • 8,557
  • 8
  • 53
  • 93

1 Answers1

0

The standard atomic variables have constant-expression constructors, which means that they are initialized during the static initialization phase (i.e. at compile time). Thus there is no problem using something like an std::atomic<int> as your counter.

That said, if your program doesn't launch any threads before main starts, you probably don't have to worry too much about this anyway.

By the way, the construction you describe is also known as the nifty counter or Schwarz counter.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084