Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xcode 为什么Apple clang不允许C++;11当'时,线程为本地线程;官方';叮当声支持它_Xcode_C++11_Clang - Fatal编程技术网

Xcode 为什么Apple clang不允许C++;11当'时,线程为本地线程;官方';叮当声支持它

Xcode 为什么Apple clang不允许C++;11当'时,线程为本地线程;官方';叮当声支持它,xcode,c++11,clang,Xcode,C++11,Clang,下面是一个简单的程序,在共享库中使用非POD类型的C++11 thread_局部变量进行测试 如果我使用自制的叮当声,效果很好: > /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 m

下面是一个简单的程序,在共享库中使用非POD类型的C++11 thread_局部变量进行测试

如果我使用自制的叮当声,效果很好:

> /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
但是,如果我尝试使用Apple Clang,我会收到一条错误消息,说它不受支持:

> /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.o.d -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.
有谁能解释一下为什么苹果的clang变体cowardly拒绝接受thread_local,尽管底层编译器支持它,并且生成的代码似乎可以工作

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);
}
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)
根据:

thRead本地支持当前需要C++运行库 g++-4.8或更高版本


< P> >我相信CLAN的自制版本使用了不同的C++运行时。< /P> < P>编译器包含XCKEL 8,以后支持C++ 11代码> THEADLIX本地< /COD>关键字。此功能已添加到Xcode 8测试版,如中所述,从开始。()

问题中列出的示例程序在OS X 10.11.6下使用Xcode 8 GM编译和运行,并生成预期的输出。随后,它在macOS 10.13.4下使用Xcode 9.3重新测试,在macOS 10.14.4下使用Xcode 10.2.1重新测试,并继续按预期运行

关于iOS,我通过实验发现,iOS 9和更高版本支持
thread\u local
,但iOS 8.4或更低版本不支持


对于Xcode 7.x及更早版本,以下是2014年苹果工程师在老苹果开发者论坛(不再访问)上的回答:

我们不支持开源的线程本地实现 因为我们相信我们可以提供更高的性能 在动态环境中使用各种功能实现我们的平台 连接器这样的实现将与ABI不兼容 在开源程序中实现,所以我们不支持 线程是本地的,直到我们得到了一个可以接受的实现 可预见的未来


随后的帖子证实,Xcode 6.3仍然不支持
thread\u local

Xcode和Homebrew clang都可以使用libstdc++和libc++。因为OSX只提供GCC4.1版本的libstdc++,所以它不是C++11的初学者。所以,我肯定在使用libc++。不过,它并没有回答为什么使用libc++的自制程序可以使用thread_local,而使用libc++的XCode程序却不能。这可能最好作为评论而不是答案发布。我想@HowardHinnant知道真正的原因。“格伦道尔:我可以从浩瀚的深渊召唤灵魂。霍斯珀:为什么,我也可以,或者任何人也可以;但是当你召唤灵魂的时候,他们会来吗?”@BrettHale Apple在XCode 6中发布的官方clang是基于clang-3.5的,clang-3.5支持达尔文的thread_local。我相信在clang-3.5之前的版本中也是如此。可能是一个bug:他们不想破坏特定功能的ABI兼容性,所以根本不提供该功能?这是精神上的。这真的很不幸。这意味着您仍然不能在可移植C++11中使用thread_local,即使现在VC14支持它。如果有苹果的工程师在读这篇文章,我真的希望你计划尽快修复。osx提供的clang截至2016年5月10日仍不支持
thread\u local
:(我看不到支持此功能的计划或前景,这很糟糕,因为
thread\u local
本可以帮助我解决性能问题。苹果最终实现
thread\u local
的方式证明了为什么上面所有的批评都是错误的。他们等到有了一个好的实现,他们可以保证会被刺伤。)这一理念正是libSystem(苹果的“CRT”)的原因所在从未破坏过二进制兼容性,而微软在每次修改编译器时都要发布一个新的
msvcrXYZ.dll
/
vcruntimeXYZ.dll
。我正在确认@rsfinn从2016年6月29日开始的注释。Xcode 8确实支持
线程本地
,于2016年9月20日测试。我对@alexchandel关于他们实现它的方式,但我的任务太多,无法充分研究它。
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)