8

C++11 offers features like thread-safe initialization of static variables, and citing that question we'll say for instance:

Logger& g_logger() {
    static Logger lg;
    return lg;
}

So ostensibly (?) this is true regardless of whether a module compiled with a C++11 compiler included the thread headers, or spawned any threads in its body. You're offered the guarantee even if it were linked against another module that used C++11 threads and called the function.

But what if your "other module" that calls into this code wasn't using C++11 threads, but something like Qt's QThread. Is atomic initialization of statics then outside of the scope of C++11's ability to make such a guarantee? Or does the mere fact of a module having been compiled with C++11 and then linked against other C++11 code imply that you will get the guarantee regardless?

Does anyone know a good reference where issues like this are covered?

Community
  • 1
  • 1
  • static initialization is a language property. I don't see how this can be affected by a specific library. – pmr Mar 07 '12 at 20:12
  • 2
    @pmr It seems a little tricky to me because--for instance--the memory for the above static is allocated at the beginning of the program, but the constructor runs the first time the function with the static inside of it gets called. It would seem to require an omniscience about the underlying thread model to achieve this, so I am skeptical it could get it right if mixing QThread/C++11thread...though there is a slight chance of new binary requirements that make it work. – HostileFork says dont trust SE Mar 07 '12 at 20:17
  • @HostileFork: As long as both (c++ and qt) use the same OS facilities for threading, I don't see how something could go wrong. Also I don't see why any of both should not use the OS threading facilities. – PlasmaHH Mar 07 '12 at 20:22
  • 2
    The underlying thread model is known though. QThreads are just a wrapper. They are implemented in a C++ library, and so they behave like C++ says threads should behave. The C++ standard describes "threads of execution". It doesn't say that they have to be created as `std::thread` objects. pthread, Boost.Thread and QThread are all valid threads of execution according to C++11 – jalf Mar 07 '12 at 20:56

2 Answers2

7

Does anyone know a good reference where issues like this are covered?

Sure. The C++ standard. It describes the behavior of C++ code. If your library is C++ code, it is required to follow this behavior. So yes, you get the same guarantees as if it had been your own code.

Exactly how the compiler/runtime/OS/everything else pulls it off is Not Your Problem. The C++ standard guarantees that it is taken care of.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • Point taken. Yet regardless of Whether It Is My Problem Or Not, I would like to know if I use GCC and Qt if they did the magic to "pull it off". From a tech standpoint, if a C++03 `static.a` library were linked into a C++11 `icallthestatic` executable it's unlikely the linker would be able to do this. But that points to a broader issue of "you probably can't link C++03 code with C++11 and get C++11 guarantees for the system"... – HostileFork says dont trust SE Mar 08 '12 at 21:49
  • C++03 code is only guaranteed to behave like C++03. So if you link to a C++03 library, you can't count on it implementing guarantees provided only by C++11 – jalf Mar 09 '12 at 08:37
4

Your example relies on the memory model, not on how threads are implemented. Whoever executes this code will execute the same instructions. If two or more cores execute this code, they will obey the memory model.

The basic implementation is equivalent to this:

std::mutex mtx;
Logger * lg = 0;
Logger& g_logger() {
    std::unique_lock<std::mutex> lck(mtx);
    if (lg == 0)
        lg = new Logger;
    return *lg;
}

This code may be optimized to use the double-checked locking pattern (DCLP) which, on a particular processor architecture (e.g., on the x86) might be much faster. Also, because the compiler generates this code, it will know not to make crazy optimizations that break the naive DCLP.

Bartosz Milewski
  • 11,012
  • 5
  • 36
  • 45
  • Cool, thanks...looks like there's consensus that this is *supposed* to be safe. FYI: The reason I was looking into it was to address this scenario... http://stackoverflow.com/questions/9507973/how-to-mitigate-user-facing-api-effect-of-shared-members-in-templated-classes – HostileFork says dont trust SE Mar 09 '12 at 07:33