使用 clang 的特征检查宏检测是否存在 std::launder

Using clang's feature checking macros to detect existence of std::launder

我必须使用不同版本的 clang 编译相同的代码。由于代码包含一些 c++17 功能,并非每个版本的 clang 都支持这些功能,因此我想在编译时检查它们是否受支持。据我所知,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 机制,但这似乎有点矫枉过正,我仍然有兴趣找出实际问题所在。

从link到您给的评论,在(库函数)的实现中std::launder

#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER 
  return __builtin_launder(__p); 
#else
  return __p;
#endif
}
如果没有内置函数,

std::launder 也在那里。因此,内置函数的存在或 non-existence 不会告诉您 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

参见 https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations。你应该测试 __cpp_lib_launder,但 libc++ 似乎没有在我的版本中实现它......