0

The following is thread safe since each array element is accessed by only one thread (including the real world part not shown here):

static bool myArray[THREAD_COUNT] = {false}; // Only used in DoSomething()

void DoSomething(uint8_t threadIndex)
{
   myArray[threadIndex] = true;
   // Real world function is more complex
}

Now consider the following code:

void DoSomething(uint8_t threadIndex)
{
   static bool myArray[THREAD_COUNT] = {false};
   myArray[threadIndex] = true;
   // Real world function is more complex
}

Is this function threadsafe too (especially considering the array initialization that takes place at first call of the function, not at startup)?

Silicomancer
  • 8,604
  • 10
  • 63
  • 130
  • A global variable or a local `static` variable are basically the same. All you have changed is really just the scope (practically speaking). And initialization of local `static` variables is thread-safe. – Some programmer dude Jan 25 '17 at 15:38
  • Are we sure that initialization of a **static** local variable is made upon the first call to the subroutine? I'm not - can somebody confirm? – linuxfan says Reinstate Monica Jan 25 '17 at 15:47
  • @linuxfan I don't think there is a standard requirement about it as it doesn't affect the semantics. But the common implementation is to place the initialized variables with static storage into the dedicated `.data` section in the binary during compile time. Actually it wouldn't make sense to force the compiler to include a *one time* initialization code into a function. Such a code will require some extra tracking (some other static variables?). Update: Hey, look, there **is** a standard requirement... – Eugene Sh. Jan 25 '17 at 15:54
  • "considering the array initialization that takes place at first call of the function, not at startup" - That's wrong. Initialisation of static objects is completed before `main` is called. An assignment is not an initialisation. – too honest for this site Jan 25 '17 at 16:06
  • 1
    I would not bet on this. Use C11 `_Thread_local` to be on the safe side. As a personal note: I'd rather have the array outside the function body, properly documented. – too honest for this site Jan 25 '17 at 16:09
  • @Olaf Where did I get that idea? Are local statics in C++ initialized on first function call? – Silicomancer Jan 25 '17 at 16:14
  • @Silicomancer, nops, local statics are also initialized at program startup in C++ – David Ranieri Jan 25 '17 at 16:18
  • @Silicomancer: This is C, not C++! Therefore I commented in C context. I'm not a clairvoyant, so how would I know why you thought that? – too honest for this site Jan 25 '17 at 16:19
  • @KeineLust Here they say something different: http://stackoverflow.com/q/55510/1421332 – Silicomancer Jan 25 '17 at 16:20
  • @Olaf I know, just trying to understand the differences – Silicomancer Jan 25 '17 at 16:20
  • @Silicomancer: The actual question is: why do you assume two different languages have to behave identical= (retorical question, let's not discuss this further) – too honest for this site Jan 25 '17 at 16:21
  • @Silicomancer I don't think there's anything contrary in the the question you linked to. An answer by Arkadiy quotes the same from C++ standard and other answers, albeit experimental in nature, says/shows the same. – P.P Jan 25 '17 at 16:28
  • @P.P. Sorry, you lost me. All those answers behind the link say that static locals in C++ are initialised on usage. Not on startup and not on function call. While for C99 you quoted that it is done at/before startup. In which way is this compatible? – Silicomancer Jan 25 '17 at 16:44

1 Answers1

3

It's safe. All objects with static storage duration are initialized before program startup. That means even before any threads come into play.

5.1.2 Execution environments:

Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. Program termination returns control to the execution environment.

(emphasis mine).

C99 didn't have the concept of threads. But that's how I'd interpret the above quote from the standard.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • OT: Is it my impression or people still prefers POSIX threads over C11 threads? – David Ranieri Jan 25 '17 at 16:03
  • Interesting. Wait... were did I get the idea local statics are initialized on first function call? Is it that way in C++? – Silicomancer Jan 25 '17 at 16:05
  • You should update your links to the current standard (final draft actually): http://port70.net/~nsz/c/c11/n1570.html – too honest for this site Jan 25 '17 at 16:07
  • @Olaf The question is specifically about C99. So, it's appropriate to quote C99 (draft). – P.P Jan 25 '17 at 16:08
  • 1
    @KeineLust C11 threads support isn't widely available (notably glibc doesn't provide it yet). So, most still prefer POSIX threads I guess. – P.P Jan 25 '17 at 16:09
  • @P.P.: Sorry, I oversaw the c99 tag at the question. – too honest for this site Jan 25 '17 at 16:10
  • @Silicomancer C++ standard says something quite similar too. From C++14 (N3797 draft): *Every object of static storage duration is zero-initialized at program startup before any other initialization takes place. In some cases, additional initialization is done late*. – P.P Jan 25 '17 at 16:13