Why does Apple clang forbid C ++ 11 thread_local when the "official" clang supports it

The following is a simple program that tests using a C ++ 11 thread_local thread variable of type non-POD in a shared library.

If I use a homemade clang, this works fine:

> /usr/local/Cellar/llvm/3.5.0_2/bin/clang --version clang version 3.5.0 (tags/RELEASE_350/final) Target: x86_64-apple-darwin14.0.0 Thread model: posix > cmake .. -G Ninja -DCMAKE_C_COMPILER=/usr/local/Cellar/llvm/3.5.0_2/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/Cellar/llvm/3.5.0_2/bin/clang++ -- The C compiler identification is Clang 3.5.0 -- The CXX compiler identification is Clang 3.5.0 -- Check for working C compiler using: Ninja -- Check for working C compiler using: Ninja -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler using: Ninja -- Check for working CXX compiler using: Ninja -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done > ninja all ... > ./main XXX LifeCycle::LifeCycle 0x7fedc0c04b90 X before: -17 XXX LifeCycle::LifeCycle 0x7fedc0c04c10 X before in thread: -17 X after in thread: 2 XXX LifeCycle::~LifeCycle 0x7fedc0c04c10 X after: 1 XXX LifeCycle::~LifeCycle 0x7fedc0c04b90 

However, if I try to use Apple Clang, I get an error saying that it is not supported:

 > /usr/bin/clang --version Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) Target: x86_64-apple-darwin14.0.0 Thread model: posix > cmake .. -G Ninja -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -- The C compiler identification is AppleClang 6.0.0.6000056 -- The CXX compiler identification is AppleClang 6.0.0.6000056 -- Check for working C compiler using: Ninja -- Check for working C compiler using: Ninja -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler using: Ninja -- Check for working CXX compiler using: Ninja -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: > ninja all [1/4] Building CXX object CMakeFiles/lib.dir/lib.cpp.o FAILED: /usr/bin/clang++ -Dlib_EXPORTS -Wall -std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++ -fPIC -MMD -MT CMakeFiles/lib.dir/lib.cpp.o -MF CMakeFiles/lib.dir/lib.cpp.od -o CMakeFiles/lib.dir/lib.cpp.o -c ../lib.cpp ../lib.cpp:23:5: error: thread-local storage is unsupported for the current target thread_local LifeCycle lc; ^ 1 error generated. ninja: build stopped: subcommand failed. 

Could someone make it clear why the Apple clang variant cowardly refuses to abide by thread_local even though the base compiler supports it and the generated code works?

lib.h:

 #pragma once int doit(int) __attribute__((__visibility__("default"))); 

lib.cpp:

 #include "lib.h" #include <thread> #include <cstdlib> #include <cstdio> namespace { class LifeCycle { public: LifeCycle() : x(-17) { printf("XXX LifeCycle::LifeCycle %p\n", this); } ~LifeCycle() { printf("XXX LifeCycle::~LifeCycle %p\n", this); } int x; }; thread_local LifeCycle lc; } // namespace int doit(int arg) { printf("X before: %d\n", lc.x); lc.x = arg; std::thread xwriter([arg]() { if (lc.x == arg) abort(); printf("X before in thread: %d\n", lc.x); lc.x = arg + 1; printf("X after in thread: %d\n", lc.x); }); xwriter.join(); printf("X after: %d\n", lc.x); return (lc.x == arg ? EXIT_SUCCESS : EXIT_FAILURE); } 

main.cpp:

 #include "lib.h" int main(int argc, char* argv[]) { return doit(argc); } 

CMakeLists.txt:

 cmake_minimum_required(VERSION 3.1) set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++") add_library(lib SHARED lib.cpp) add_executable(main main.cpp) target_link_libraries(main lib) 
+23
c ++ 11 xcode clang
Jan 22 '15 at 17:16
source share
2 answers

The clang compiler, included in Xcode 8 and later, supports the thread_local C ++ 11 keyword. This functionality has been added to the beta version of Xcode 8, as discussed in WWDC 2016 "What's New in LLVM" video , starting at 5:50 . ( external transcript )

The sample program listed in the question compiles and runs with Xcode 8 GM under OS X 10.11.6 and produces the intended result. It was subsequently re-tested with Xcode 9.3 under macOS 10.13.4 and with Xcode 10.2.1 under macOS 10.14.4 and continues to work as intended.

As for iOS, I experimentally discovered that thread_local supported for iOS 9 and later thread_local , but not for iOS 8.4 or earlier.




For Xcode 7.x and earlier, here is the answer from 2014 from an Apple engineer in the old Apple Developer Forum (no longer available):

We do not support the open-source implementation of thread_local from Clang, because we believe that we can provide a higher-performance implementation for our platforms using various functions in the dynamic linker. Such an implementation would be ABI-incompatible with the open source implementation in Clang, so we will not support thread_local until we get an implementation with which we can live in the foreseeable future.

The following message confirms that thread_local is still not supported in Xcode 6.3.

+42
Apr 28 '15 at 21:07
source share

According to http://clang.llvm.org/cxx_status.html :

Thread_local support currently requires a C ++ runtime library from g ++ - 4.8 or later

I believe that the home version of clang uses a different C ++ runtime.

+1
Jan 23 '15 at 2:24
source share



All Articles