5
votes

note: i'm using objective-c++ where non-compile-time constant is allowed (https://stackoverflow.com/a/12304815/3101492)

+ (Foo)sharedFoo
{ 
    static Foo *foo = [Foo new];
    return foo;
}

static initializer is expected to be run only once, but is it thread safe such that if multiple threads call +(Foo)sharedFoo at same time, is it guaranteed that [Foo new] will be run only once?

I'm asking because if so, then why is it recommended that singleton patterns in obj-C use dispatch_once like the following?

+ (Foo)sharedFoo {
    static Foo *foo = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        foo = [Foo new];
    });

    return foo;
}

i'm essentially asking why can't the first line be just

static Foo *foo = [Foo new];

and just skip dispatch_once altogether if we know static local var initialization only runs once..

edit: ah ok, i found an answer. 1. first, i realized i was using objective-c++ which allows above code to compile (and runs it during runtime instead) 2. second, compiler turns that code into the "naive" version of singleton initializer w/o dispatch_once such that it is indeed not thread-safe.

1
[Foo new] is not atomic, there may be another thread call sharedFoo before [Foo new] return. - KudoCC
If you write like this static Foo *foo = [Foo new]; , did you get an compile error Initializer element is not a compile-time constant ? - KudoCC
ahh - i just checked and we're using objective-c++ so it does allow that (i was scratching my head why my project was allowing this) - jason na
and looking for info on c++'s static initializer, i found an answer that it is indeed not thread-safe. thanks! - jason na
Since C++11, local static variable initialization is thread-safe. You can configure Xcode/Clang to use the C++11 (or C++14) dialect for your Objective-C++ project. So, in theory, it is safe in "Objective-C++11". That being said, keep in mind that the exact behaviour of Objective-C++ is not well documented... - alexk7

1 Answers

0
votes
Is local static variable initialization thread safe?

Short answer:-

No it is not thread safe.