For example, the node::node()
constructor in the following snippet accesses the globals node::count
and ::tail
without any multithread guards. Does the C++ standard guarantee that the output would always be a permutation of 0 1 2
(regardless of the order)?
#include <stdio.h>
struct node *tail;
struct node
{
static int count;
int index;
node *prev;
node()
{ index = count++; prev = tail; tail = this; }
};
int node::count;
node one, two[2];
int main(int argc, char *argv[])
{
for(node *p = tail; p; p = p->prev)
printf("%d\n", p->index);
return 0;
}
I am looking for an answer based on the (applicable) standard, not for implementation or compiler specific behaviors. There are a number of related questions on SO but it's not entirely clear how they directly apply to this particular and rather basic case ( Is C++ static member variable initialization thread-safe? , Is local static variable initialization thread-safe in C++11? etc).
Initialization of global variables is guaranteed single-threaded as long as the program doesn't itself start a thread (eg in a constructor of some global variable); once that happens, the implementation is then allowed to parallellize remaining initializations, to some extent.
[basic.start.init]/2 ...Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit. If a program starts a thread (30.3), the subsequent initialization of a variable is unsequenced with respect to the initialization of a variable defined in a different translation unit. Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit. If a program starts a thread, the subsequent unordered initialization of a variable is unsequenced with respect to every other dynamic initialization. Otherwise, the unordered initialization of a variable is indeterminately sequenced with respect to every other dynamic initialization. [ Note: This definition permits initialization of a sequence of ordered variables concurrently with another sequence. —end note ]
"Indeterminately sequenced" is the part that guarantees single-threaded execution. By definition, the notion of sequenced {before, after, indeterminately} is only meaningful within a single thread:
[intro.execution]/13 Sequenced before is a ... relation between evaluations executed by a single thread...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.