what should be the behavior in the following case:
class C {
boost::mutex mutex_;
std::map<...> data_;
};
C& get() {
static C c;
return c;
}
int main() {
get(); // is compiler free to optimize out the call?
....
}
is compiler allowed to optimize out the call to get()?
the idea was to touch static variable to initialize it before multithreaded operations needed it
is this a better option?:
C& get() {
static C *c = new C();
return *c;
}
Updated (2023) Answer:
In C++23 (N4950) any side effects of initializing a static local variable are observable as its containing block is entered. As such, unless the compiler can determine that initializing the variable has no visible side effects, it will have to generate code for to call
get()at the appropriate time (or to execute an inlined version ofget(), as the case may be).Contrary to earlier standards, C++ 23 no longer gives permission for dynamic initialization of a static local variable to be done "early" (as discussed below).
[stmt.dcl]/3:
Original (2010) answer:
The C and C++ standards operate under a rather simple principle generally known as the "as-if rule" — basically, that the compiler is free to do almost anything as long as no conforming code can discern the difference between what it did and what was officially required.
I don’t see a way for conforming code to discern whether
getwas actually called in this case, so it looks to me like it’s free to optimize it out.At least as recently as N4296, the standard contained explicit permission to do early initialization of static local variables:
So, under this rule, initialization of the local variable could happen arbitrarily early in execution, so even if it has visible side effects, they’re allowed to happen before any code that attempts to observed them. As such, you aren’t guaranteed to see them, so optimizing it out is allowed.