我必须使用不同版本的clang编译相同的代码。由于代码包含了每个clang版本都不支持的一些c ++ 17特性,我想在编译期间检查它们是否受支持。据我所知,clang的feature checking macros是正确的方法。
我的问题特别出现在std :: launder上。
我创建了这个最小的例子:
#include "iostream"
#if __has_builtin(__builtin_launder)
void test() {
int i = 42;
std::cout << "Should compile: " << std::launder(&i) << std::endl;
}
#else
void test() {
int i = 42;
std::cout << "Should not even compile: " << std::launder(&i) << std::endl;
}
#endif
int main(){
test();
}
如果我正在使用clang++ -std=c++1z -stdlib=libc++ -Wall -pedantic test3.cpp && ./a.out
编译它(clang版本6.0.0,libc ++)
输出是:
Should not even compile: 0x7fff75116f64
虽然显然支持std :: launder,但内置检查不起作用。由于它与reviews llvm: Implement std::launder中的检查相同,因此我假设检查是正确的。
我错过了什么?我觉得这很简单,但我没有看到它。
最糟糕的情况是,为了这个目的,我使用cmake的try-compile机制,但它似乎是一种矫枉过正,我仍然有兴趣找出实际问题是什么。< / p>
答案 0 :(得分:6)
从您提供的评论链接到(库函数)std::launder
的实现:
#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
return __builtin_launder(__p);
#else
return __p;
#endif
}
如果没有内置, std::launder
也有。因此内置的存在或不存在不会告诉你std::launder
是否存在。
要测试你是否有std::launder
(这似乎是你想要的),你可以使用你的配置系统(cmake,autoconf,...)或试试新的运气(C + +17)特征测试:
#include <new> // important!
#if __cpp_lib_launder >= 201606
// have std::launder for sure
#else
// not sure, could've std::launder either way
#endif
答案 1 :(得分:3)
见https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations。您应该测试__cpp_lib_launder
,但libc ++似乎没有在我的版本中实现...