【问题标题】:Checking for C++11 library features检查 C++11 库功能
【发布时间】:2012-08-09 15:00:36
【问题描述】:

检查标准库的特定 C++11 功能是否存在的好方法。

对于编译器功能,我只是顺便检查了 (IMHO) 主要编译器的编译器版本(VC++gccclang 目前,也许 Intel) 虽然这不是最好和最灵活的方法,但我不知道有什么更好的方法,除了 clang 具有真正的不错 __has_feature 宏。

但对于与编译器没有那么严格耦合的库功能来说,情况就更糟了。目前,我想使用相同的方法来检查 VC++ 的编译器版本(假设它使用自己的库,这很容易)。对于clang,我至少可以将__has_include 用于大规模基于标头的查询。除此之外,我想检查 __GLIBCXX__ 的值是否已定义可能是一个好主意,但是我再次找不到任何关于哪些特定 libstdc++ 版本引入了哪些功能的信息,而不是当前版本支持。

这些方法应该保留给预处理器检查等,因为我想在没有任何复杂配置过程并且不使用任何第三方库(是的,boost em> 是第三方)。

  1. 那么,在那些(相当狭窄的)条件下,我检查特定 C++11 库功能的可能性是什么。甚至可能在声明的特定函数或类型的规模上?

  2. 如果检查编译器或库版本仍然是最佳方法,我在哪里可以找到有关 特定 版本支持的特定 C++11 功能的详细信息libstdc++(也许还有其他重要的,libc++)?

FWIW 目前我对 <cstdint>、C++11 <cmath> 函数和 std::hash 感兴趣,但这可能会改变,对于一般方法来说可能并不重要。

【问题讨论】:

    标签: c++ visual-c++ c++11 libstdc++ libc++


    【解决方案1】:

    除了知道哪个编译器在哪个版本中实现了什么并且有适当的定义之外,您在这里真的没有什么好做的。

    gcc 有一个 special table 用于库功能。 __has_include 的主要问题当然是对旧版标准的补充。 libstdc++ 也有必要的包含,但这并不意味着启用这些文件内容的必要定义。它也不会告诉你任何关于可用实现的实际数量(有时是不完整的)。

    由于您有一个仅包含标头的库,因此这不适用于您,但仍然很重要:C++11 和 C++03 之间的二进制不兼容可能会卷土重来。

    我真的不会自己解决任何问题,而是使用Boost.Config。最初它仅描述语言特性,但现在已扩展到标准库头文件。

    【讨论】:

    • 编译器在实现新功能时真的很懒惰。
    • @BartekBanachewicz 不,不是真的。也许是微软。
    • 其中一些做得很好。链接:aristeia.com/C++11/C++11FeatureAvailability.htm
    • @BartekBanachewicz 不一定是这个意思,但在这种情况下它确实如此,因为他们落后了,不管实际发布频率。
    • @Bartek Banachewicz:Visual Studio 2012 的预览版比 gcc 4.6 ert 到 C++11 支持还差很远,也就是说下一个版本的微软编译器落后于上一个版本gcc 的。
    【解决方案2】:

    可以编写 autoconf 宏来检查,如果这样做,请将它们提交给 http://www.gnu.org/software/autoconf-archive/
    迄今为止唯一相关的检查是否完整覆盖,而不是单个功能:http://www.gnu.org/software/autoconf-archive/ax_cxx_header_stdcxx_0x.html#ax_cxx_header_stdcxx_0x 但这不符合没有复杂配置检查的要求。

    除此之外,我想检查 __GLIBCXX__ 的值(如果已定义)可能是个好主意,

    查看__GLIBCXX__ 的值是没有用的,it contains the date the version was released 几乎不会告诉您有关版本的任何信息(例如,4.6.3 是在 4.7.0 之后发布的,所以在__GLIBCXX__ 中有一个较晚的日期,但 C 较少++11 个特性。)在 GCC 中使用 libstdc++ 时,您希望使用 __GLIBC____GLIBC_MINOR__ 中的通用 GCC 版本号来检查版本(通常,您只能将给定版本的 libstdc++ 与它附带的 GCC 版本一起使用.)

    编辑: 从 GCC 7 开始,有一个由 libstdc++ 头文件定义的新宏 _GLIBCXX_RELEASE,它被定义为与 GCC 的 __GNUC__ 相同的值,但即使在将 libstdc++ 头文件与非 GCC 编译器一起使用。

    但话说回来,除了当前版本支持的内容之外,我找不到任何关于哪些特定 libstdc++ 版本引入了哪些功能的信息。

    以前版本的 libstdc++ C++11 状态表可在线获取所有 GCC 文档所在的位置:http://gcc.gnu.org/onlinedocs/

    对于 4.7,它位于 http://gcc.gnu.org/onlinedocs/gcc-4.7.1/libstdc++/manual/manual/status.html#status.iso.2011,对于 4.6,它位于 http://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/manual/manual/status.html#status.iso.200x,并且之前的版本包含在源代码中(但无论如何,4.6 之前的版本中的覆盖范围相当不完整。)

    每个版本的发行说明中都列出了一些新增功能,例如http://gcc.gnu.org/gcc-4.7/changes.html(在 libstdc++ 部分)

    编辑:对于 C++17 库支持,我们现在列出了首先添加该功能的版本,因此您只需查看最新文档:https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.201z

    FWIW 目前我对 <cstdint>、C++11 <cmath> 函数和 std::hash 很感兴趣

    它们应该存在于所有支持 C++0x/C++11 的 libstdc++ 版本中。

    【讨论】:

    • 当然自动工具不是选项,但感谢其余的答案。我也发现了__GLIBCXX__ 的问题(为什么还要定义这样一个无用的宏呢?),所以我使用__GNUC____GNUC_MINOR__ 进行gcc。但是在使用 libstdc++ 时该怎么办? clang,因为 clang 自己定义的 __GNUC__ 只是没用,设置为 4.2.X?
    • 好问题。我不知道那个宏的意义是什么。我们不正式支持将 libstdc++ 与其他编译器一起使用,但它可以工作(我自己也将它与 clang 一起使用),因此请随时在 GCC 的 bugzilla 中提出增强请求,要求以某种方式来识别独立于编译器的库。我会考虑如何干净地做到这一点(即从 GCC 版本中自动获取它 - 我们不想在制作新的 GCC 版本时手动设置它。)
    • 哦,所以你实际上是解决这个问题的合适人选,不知道 ;) 好吧,现在我刚刚解决了使用 __GLIBCXX__ >= 20080606 处理 clang i> 希望不再发布任何 __GNUC__ 的简单版本宏确实是一个好主意,因为可能(虽然不知道)其他编译器试图在'nixes 上默认使用libstdc++,并且知道发布日期当版本号不按时间顺序增加时,它是非常没用的。
    • 不会再有
    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    相关资源
    最近更新 更多