【发布时间】:2015-10-17 21:34:13
【问题描述】:
我认为这是No type named 'unique_ptr' in namespace 'std' when compiling under LLVM/Clang 问题的一部分。 According to Marshall Clow,我可以通过_LIBCPP_VERSION检测到-stdlib=libc++:
如果您正在编写跨平台代码,有时您需要知道什么 您正在使用的标准库。理论上,他们都应该提供 等效功能,但这只是理论。有时你只是 需要知道。检查 libc++ 的最佳方法是查找 预处理器符号_LIBCPP_VERSION。如果已定义,那么您就是 使用 libc++。
#ifdef _LIBCPP_VERSION // libc++ specific code here #else // generic code here #endif
不幸的是,这与 Apple 的 Clang (3.4-SVN) 和我从 LLVM 项目下载后从源代码构建的 Clang (3.6) 不同。我猜这个测试只在 Xcode 下有效。
如何在预处理器中可靠地检测到-stdlib=libc++?
这是测试用例:
$ cat test-clapple.cxx
// Need to test {C++03,C++11} x {libc++, no libc++}
// c++ -c test-clapple.cxx
// - OK
// c++ -stdlib=libc++ -c test-clapple.cxx
// - OK
// c++ -std=c++11 -c test-clapple.cxx
// - FAILS, no type named 'unique_ptr' in namespace 'std'
// c++ -std=c++11 -stdlib=libc++ -c test-clapple.cxx
// - OK
#include <ciso646>
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600)
# pragma message "C++11"
#elif (__cplusplus >= 199711L)
# pragma message "C++03"
#endif
#if (_LIBCPP_VERSION)
# pragma message "libc++"
#else
# pragma message "no libc++"
#endif
#if defined(__apple_build_version__)
# pragma message "Apple build"
#else
# pragma message "non-Apple build"
#endif
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600) // C++11
# include <memory>
#else
# include <tr1/memory>
#endif
// Manage auto_ptr warnings and deprecation in C++11
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif // C++11
int main(int argc, char* argv[])
{
return argc;
}
此项目不使用 Autotools、Cmake、Boost 或其他外部库或框架。
【问题讨论】:
-
Xcode 并不神奇;你确定这还没有准备好去吗? Xcode 可能会在命令行上为您设置
_LIBCPP,但它似乎更有可能是由 libc++ 本身设置的,不是吗? -
_LIBCPP_VERSION是正确的检查,但您必须在定义之前实际包含标准库头文件。 -
所以也许你在包含库头文件之前检查了宏?如果库头定义了宏,那将不起作用。你能展示一个特定的最小程序和编译器调用来证明这个问题吗?
-
您的测试用例是错误的,因为在尝试测试正在使用的标准库实现之前,您没有包含标准库头文件。请看下面我的回答。无论如何,这可能并不重要,因为您所说的问题是基于另一个错误的前提。
标签: c++ clang llvm c-preprocessor libc++