【问题标题】:Using clang's feature checking macros to detect existence of std::launder使用 clang 的功能检查宏来检测 std::launder 的存在
【发布时间】:2018-09-17 05:55:28
【问题描述】:

我必须使用不同版本的 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 &amp;&amp; ./a.out编译它(clang 版本 6.0.0,libc++)
输出是: Should not even compile: 0x7fff75116f64

虽然明显支持 std::launder,但内置检查不起作用。由于它与reviews llvm: Implement std::launder 中的检查相同,因此我假设检查是正确的。

我错过了什么?我觉得它是超级简单的东西,但我没有看到它。

在最坏的情况下,我会为此目的使用 cmake 的 try-compile 机制,但这似乎有点矫枉过正,我仍然有兴趣找出实际问题所在。

【问题讨论】:

    标签: c++ c++17 clang++


    【解决方案1】:

    从你给出的评论的链接,在(库函数)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
    

    【讨论】:

    • 感谢您的回复,但 _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER 是使用 __builtin_launder 定义的,所以我不明白那应该如何工作。请参阅:#if __has_builtin(__builtin_launder) #define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER #endif
    • 是的,但是如果找不到内置函数,则使用上面 sn-p 中的#else。它不会禁用std::launder,它只是改变了它的实现。
    【解决方案2】:

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

    【讨论】:

    • 你#include &lt;new&gt;了吗?
    • @DanielJour 是的,我做到了。我还使用grep 来检查它是否没有出现在源代码中的任何位置。我有 6.0 版(linux debian 包)。
    猜你喜欢
    • 2011-02-09
    • 1970-01-01
    • 2015-03-25
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多