Hi all, I'm wondering whether static constant variables are thread-safe or not?
Example code snippet:
void foo(int n)
{
static const char *a[] = {"foo","bar","egg","spam"};
if( ... ) {
...
}
}
Hi all, I'm wondering whether static constant variables are thread-safe or not?
Example code snippet:
void foo(int n)
{
static const char *a[] = {"foo","bar","egg","spam"};
if( ... ) {
...
}
}
In your example the pointer itself can be considered as thread safe. It will be initialized once and won't be modified later.
However, the content of the memory pointed won't be thread-safe at all.
In this example, a
is not const
. It's an array of pointers to const
strings. If you want to make a
itself const
, you need:
static const char *const a[] = {"foo","bar","egg","spam"};
Regardless of whether it's const
or not, it's always safe to read data from multiple threads if you do not write to it from any of them.
As a side note, it's usually a bad idea to declare arrays of pointers to constant strings, especially in code that might be used in shared libraries, because it results in lots of relocations and the data cannot be located in actual constant sections. A much better technique is:
static const char a[][5] = {"foo","bar","egg","spam"};
where 5 has been chosen such that all your strings fit. If the strings are variable in length and you don't need to access them quickly (for example if they're error messages for a function like strerror
to return) then storing them like this is the most efficient:
static const char a[] = "foo\0bar\0egg\0spam\0";
and you can access the n
th string with:
const char *s;
for (i=0, s=a; i<n && *s; s+=strlen(s)+1);
return s;
Note that the final \0
is important. It causes the string to have two 0 bytes at the end, thus stopping the loop if n
is out of bounds. Alternatively you could bounds-check n
ahead of time.
To be really safe you should do
static char const*const a[]
this inhibits modification of the data and all the pointers in the table to be modified.
BTW, I prefer to write the const
after the typename such that it is clear at a first glance to where the const
applies, namely to the left of it.
Any variable that is never modified, whether or not it's explicitly declared as const, is inherently thread-safe.
static const char *a[] = {"foo","bar","egg","spam"};
In C that would be always thread safe: the sructures would be already created at compile time, thus no extra action is taken at run time, thus no race condition is possible.
Beware the C++ compatibility though. Static const object would be initialized on the first entry into the function, but the initialization is not guaranteed to be thread-safe by the language. IOW this is open to a race condition when two different threads come into the function simultaneously and try to initialize the object in parallel.
But even in C++, POD (plain old data: structures not using C++ features, like in your example) would behave in the C compatible way.