我正在测试一个问题,该问题最近在使用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
答案 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。对我来说,显然该功能不可用。