![]() |
Initialization of local statics
Hi,
the following code #include <stdio.h> struct A { A() { puts("A()"); } ~A() { puts("~A()"); } }; static const A& foo() { puts("foo()"); static const A var; return var; } int main() { puts("main()"); foo(); foo(); return 0; } prints main() foo() A() foo() ~A() So var inside foo is initialized after the first pass of the code over the variable definition. Well, that would be useful in conjunction with templates to achieve late initialization and avoid static initialization dependencies. But is this execution order guaranteed? (I guess yes.) And if so, what does this mean with respect to threads? If this is not thread safe one could never store non POD constants in local statics in a multi threaded application, even if the underlying object type provides thread safety for const methods, isn't it? Marcel |
Re: Initialization of local statics
Marcel Müller <news.5.maazl@spamgourmet.org> wrote:
> But is this execution order guaranteed? (I guess yes.) AFAIK, yes. It can sometimes be a handy trick for executing code lazily only when needed (code which has to be executed only once, of course), without having to explicitly put a boolean somewhere to see if the code has already been executed or not, for example: void foo() { static SomeClass someObject = someReallyExpensiveFunction(); ... } > And if so, what > does this mean with respect to threads? AFAIK the current standard takes no stance on thread-safety on anything (I'm not even sure it does so even for malloc()/new, even though in practical implementations those always are). Hence I don't think the standard guarantees thread-safety for initializing local statics either. (In other words, if two threads call the function simultaneously, the initialization of the static object might get screwed up, unless the compiler itself guarantees mutual exclusion.) |
Re: Initialization of local statics
Juha Nieminen wrote:
>> And if so, what >> does this mean with respect to threads? > > AFAIK the current standard takes no stance on thread-safety on anything > (I'm not even sure it does so even for malloc()/new, even though in > practical implementations those always are). Hence I don't think the > standard guarantees thread-safety for initializing local statics either. > (In other words, if two threads call the function simultaneously, the > initialization of the static object might get screwed up, unless the > compiler itself guarantees mutual exclusion.) Just decompiled the binary. You are right, at least gcc 3.3.5 makes absolutely no protection around the flag. Maybe because it might be quite expensive, since other threads must be blocked during the initialization. Of course, the runtime overhead on each evaluation can be close to zero by using a double check. But we still need a synchronization resource for each static object. This is most likely the major drawback. Marcel |
Re: Initialization of local statics
Marcel Müller <news.5.maazl@spamgourmet.org> writes:
> But is this execution order guaranteed? (I guess yes.) And if so, what > does this mean with respect to threads? The C++03 standard doesn't say anything about threads at all, and so any compiler that supports threads can do whatever it likes. gcc has a compiler flag that selects whether or not such initialization is thread-safe, for example. The upcoming C++0x standard requires that the initialization of local-statics is thread-safe. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976 |
Re: Initialization of local statics
Anthony Williams wrote:
> The upcoming C++0x standard requires that the initialization of > local-statics is thread-safe. Ah! Nice to know. Even though I can't wait for this. Marcel |
Re: Initialization of local statics
Paavo Helde wrote:
> Marcel Müller <news.5.maazl@spamgourmet.org> wrote in news:4c9f442d$0 > $6974$9b4e6d93@newsspool4.arcor-online.net: > >> static const A& foo() >> { puts("foo()"); >> static const A var; >> return var; >> } > [...] >> If this is not thread safe one could never store non POD constants in >> local statics in a multi threaded application, even if the underlying >> object type provides thread safety for const methods, isn't it? > > For making this thread-safe there is a simple approach not involving any > locking: just make sure that any such function is called at least once in > the beginning of main(), before any extra threads are created. This > assumes of course that no threads are created directly or indirectly > from constructors of static objects. Well, it might be not that simple to call a member function deep in the business logic without even having an object of the appropriate type. Furthermore if there is no need for delayed initialization, you could simply move the static object outside the method implementation in the compilation unit to achieve the same automatically. But then we are talking about the static initialization hell. > Note that there is a similar rule for program shutdown: one should take > care that all created threads are properly joined before program exit, so > the statics are destroyed in single-threaded mode. Never heard of that. But of course, it is straight forward to do so. Calling exit() with several active threads makes no sense anyway. Depending on the platform the result is completely different. WinXX AFAIK ends the application not before the last thread died. OS/2 implicitly cancels all threads unconditional if thread 1 dies. Marcel |
| All times are GMT. The time now is 07:56 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.