错误:'uncaught_exceptions'不可用:macOS 10.12中引入

时间:2018-11-11 21:44:42

标签: macos exception clang c++17 feature-detection

我正在测试一个问题,该问题最近在使用C ++ 17进行测试期间浮出水面。这是源文件:

$ cat test.cxx
#if __EXCEPTIONS && __has_feature(cxx_exceptions)
# include <exception>
# define CXX17_EXCEPTIONS 1
#endif

void Foo()
{
#if defined(CXX17_EXCEPTIONS)
    if (std::uncaught_exceptions() == 0)
#endif
    {
        int x = 0;
    }
}

并在Mac OS X 10.8或10.9上使用Macports编译器进行编译:

$ /opt/local/bin/clang++-mp-5.0 -std=gnu++17 test.cxx -c
test.cxx:9:14: error: 'uncaught_exceptions' is unavailable: introduced in macOS 10.12
    if (std::uncaught_exceptions() == 0)
             ^
/opt/local/libexec/llvm-5.0/include/c++/v1/exception:130:63: note:
      'uncaught_exceptions' has been explicitly marked unavailable here
_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_e...
                                                              ^
1 error generated.

/opt/local/bin/clang++-mp-5.0也遇到了这个问题。这似乎不是一个一次性的问题。 4.0拒绝-std=gnu++17,因此我无法再进行测试。

根据Clang 3.6 Release Notes,我认为我对std::uncaught_exceptions()使用了正确的测试:

  

要可靠地测试是否启用了C ++异常,请使用__EXCEPTIONS &&   __has_feature(cxx_exceptions),否则在Objective-C ++文件中的所有版本的Clang中都无法正常工作。

我可能将无法包含Apple特定的头文件,因此无法测试OS X 10.12。其他人也遇到了这个问题,但是我没有找到合适的解决方案。例如,此bug report存在未解决的问题。

在包含标准C ++预处理器宏和功能测试的Apple平台上,是否可以解决此问题?如果是这样,什么方法或测试?


$ /opt/local/bin/clang++-mp-6.0 --version
clang version 6.0.1 (tags/RELEASE_601/final)
Target: x86_64-apple-darwin13.4.0
Thread model: posix
InstalledDir: /opt/local/libexec/llvm-6.0/bin

$ /opt/local/bin/clang++-mp-5.0 --version
clang version 5.0.2 (tags/RELEASE_502/final)
Target: x86_64-apple-darwin13.4.0
Thread model: posix
InstalledDir: /opt/local/libexec/llvm-5.0/bin

3 个答案:

答案 0 :(得分:3)

这里的问题是Mac OS 10.12之前发行的运行时库(libc++.dylib)不包含std::uncaught_exceptions()的定义。如果要在这些平台上尝试使用它,则会导致链接器错误。因此,相反,我们在编译时警告您这将失败。这与可用/不可用的异常无关:这与特定功能不可用有关。

答案 1 :(得分:1)

__EXCEPTIONS && __has_feature(cxx_exceptions)测试异常是否可用。例外是自1990年以来就已在C ++中使用的一种语言功能(C ++ 17中未引入它们!),因此,除非您明确禁用例外,否则它们应始终可用。

__cpp_lib_uncaught_exceptions才是正确的测试。

答案 2 :(得分:0)

我不确定这是否是处理情况的正确方法,但可能会对其他人有所帮助。

$ cat test.cxx
#if __EXCEPTIONS && __has_feature(cxx_exceptions)
# if __cpp_lib_uncaught_exceptions
#  include <exception>
#  define CXX17_EXCEPTIONS 1
# endif
#endif

void Foo()
{
#if defined(CXX17_EXCEPTIONS)
    if (std::uncaught_exceptions() == 0)
#endif
    {
        int x = 0;
    }
}

__EXCEPTIONS && __has_feature(cxx_exceptions)特定于Clang,并检测C ++ 17异常(包括ObjectiveC ++)是否可用。 __cpp_lib_uncaught_exceptions是一种C ++语言功能,可检测C ++ 17异常是否可用。

我不清楚在C ++ 17异常不可用时__has_feature(cxx_exceptions)如何返回true。对我来说,显然该功能不可用。

另请参阅LLVM Issue 39631, __has_feature(cxx_exceptions) returns true but fails to compile std::uncaught_exceptions()