【问题标题】:What is the value of __cplusplus for C++17?C++17 的 __cplusplus 值是多少?
【发布时间】:2016-11-22 04:57:36
【问题描述】:

我们正在尝试在 C++17 及其 change to std::uncaught_exception 下测试一些代码。我似乎无法让 GCC 提供 __cplusplus 的值:

$ /opt/local/bin/g++ -std=c++17 -dM -E - </dev/null | grep __cplusplus
cc1: warning: command line option '-std=c++1z' is valid for C++/ObjC++ but not for C
$

还有:

$ /opt/local/bin/g++ --version
g++-mp-6 (MacPorts gcc6 6.1.0_0) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.

使用C++17时__cplusplus的值是多少?

【问题讨论】:

  • 添加开关-xc++(虽然它仍然可能不正确)
  • 我认为最新的标准草案仍然具有旧的 C++14 值,因此还没有正式的值。
  • 如果你只想测试std::uncaught_exceptions是否可用,你应该使用feature testing macro__cpp_lib_uncaught_exceptions
  • 感谢 Galik。 GCC 应该调用 cc1plus 而不是 cc1...现在在 GCC 错误跟踪器上打开:Issue 71930: g++ invokes the wrong preprocessor
  • 感谢 cpplearner。我猜(这只是一个猜测)一些编译器不会使用__cpp_lib_uncaught_exceptions。我想到了微软的 VC++ 和 SunCC。我发现__cplusplus 是一个更好的测试,因为它使用宽刷子进行绘画。然后我可以一次性使用那些做自己的事情的编译器,通常是 VC++。

标签: c++ macros c++17


【解决方案1】:

tl;dr:对于 C++17,__cplusplus201703L

使用C++17时__cplusplus的值是多少?

根据草案标准N4594§16.8/p1 预定义宏名称 [cpp.predefined]Emphasis Mine):

以下宏名称应由实现定义: __cplusplus 名称 __cplusplus 定义为值 201402L 编译 C++ 翻译单元时。156

156) 本标准的未来版本旨在 用更大的值替换这个宏的值。不合格 编译器应该使用最多五个十进制数字的值。

但是,为 C++14 标准指定了相同的值。显然,目前还没有为 C++17 标准设置官方/标准 __cplusplus 值。

在 GCC 版本 6.1 和 7.0 中,该值更改为 201500

Live Demo

在 Clang 版本 3.8 和 3.9 中,该值保持不变201406

因此,您必须稍等片刻才能得出标准值。

--- 更新---

根据 C++ 标准§19.8/p1 预定义的宏名称 [cpp.predefined]Emphasis Mine):

1 以下宏名称应由 实现:

__cplusplus 整数字面量201703L

因此,使用C++17时__cplusplus的值应为201703L

【讨论】:

  • 啊,我错过了你的更新...我看到 g++ -x c++ -std=c++14 -dM -E - &lt;/dev/null 为 GCC 7.3 返回 #define __cplusplus 201402L
  • 我认为 __cplusplus 在将语言选项专门设置为 c++17 时不会为 Visual Studio 2017 返回相同的值?我在使用宏时返回了199711
  • 嗯,好吧,这实际上是一个开放的错误...developercommunity.visualstudio.com/content/problem/120156/…
【解决方案2】:

我会尝试:

#if __cplusplus > 201402L
  // C++14 code here
  ...
#endif

换句话说,超过 C++14 的测试应该会随着编译器添加更多功能而工作。如上所述,GCC 使用201500L。看起来 clang 使用了201406L(我猜是 C++14 四个月后)。

使用上面的 sn-p 应该是跨平台的,即使在 C++17 出现 __cplusplus 的实际价值时也可以工作。有关不断发展的功能的更多详细信息,请尝试feature test macros

【讨论】:

  • 就我个人而言,我认为 SD-6 应该包含 __cpp_1998 __cpp_2011 宏,这些宏可以为您提供确切的月份和年份。
  • 哪个更正确?说#if __cplusplus &gt;= 201703L#if __cplusplus &gt; 201402L
  • @alfC #if __cplusplus &gt; 201402L 在 c++1z、17、当前 2a... 等上是正确的,但在 c++14 或更早版本上则不然。换句话说,这在使用 2017 年 3 月之前的任何旧编译器时很有用,因为您正在使用旧编译器已经提供的 c++17 的即用型功能。使用最近的编译器时,我更喜欢&gt;= 201703L
  • 201500L 用于 c++17 之前的版本。所以它不会与 c++14 冲突,也不是完整的 C++17 编译器......(例如,[[fallback]] 属性即使被半识别也无法正常工作。)
【解决方案3】:

通常您应该使用__cplusplusdefine 来检测c++17,但默认情况下,微软编译器没有正确定义该宏,请参阅https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - 您需要修改项目设置以包含/Zc:__cplusplus 开关,或者你可以使用这样的语法:

#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
     //C++17 specific stuff here
#endif

【讨论】:

    【解决方案4】:

    我知道你问这个问题时引用了 Gnu C++ 编译器作为你正在使用的编译器,但你可能想了解 Visual C++ 编译器发生了什么,严格来说,你的问题没有问一个特定的编译器。

    目前,截至本文发布之日,VC++ 2017 编译器将 __cplusplus 设置为 199711L,而不是您将编译器设置为使用 c++17 时所期望的。

    要让它正确报告,您还必须设置/Zc:__cplusplus

    (来源:https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017

    为什么?嗯……用他们的话来说:

    我们尝试默认更新宏,发现很多 当我们更改值时,代码无法正确编译 __cplusplus.

    (来源:https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/

    【讨论】:

      【解决方案5】:

      我真的不知道为什么__cplusplus 不显示为常规宏,但我猜是这样你无法重新定义它。这就是我确定它的价值的方式。

      #include <iostream>
      int main( int argc, char** argv )
      {
        std::cout << __cplusplus << std::endl;
        return 0;
      }
      

      然后编译显示值。

      $ g++-6 test.cpp && ./a.out
      201402
      $ g++-6 -std=c++17 test.cpp && ./a.out
      201500
      

      我会检查它是否是&gt;= 201500,而不是检查任何特定值。

      【讨论】:

        【解决方案6】:

        现代编译时检查,您可以将其放入任何需要它的文件中:

        static_assert(__cplusplus >= 201703L, "This file expects a C++17 compatible compiler.");
        

        【讨论】:

          猜你喜欢
          • 2019-05-02
          • 1970-01-01
          • 2019-11-27
          • 2014-06-04
          • 1970-01-01
          • 1970-01-01
          • 2011-11-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多