__cplusplus对于C++17的值是多少

What is the value of __cplusplus for C++17?

本文关键字:多少 C++17 cplusplus 对于      更新时间:2023-10-16

我们正在尝试测试C++17下的一些代码及其对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的值是多少?

tl;dr:对于C++17,__cplusplus就是201703L

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

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

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

156)本标准的未来版本将此宏的值替换为更大的值。不合格编译器应该使用最多包含五位小数的值

然而,对于C++14标准指定了相同的值。显然,似乎还没有为C++17标准设置官方/标准的__cplusplus值。

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

实时演示

Clang版本3.8和3.9中的值保持不变2201406

因此,您将不得不等待一段时间,等待标准值出来。

---更新---

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

1下列宏名称应由实现:

__cplusplus整数文本201703L

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

我会尝试:

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

换句话说,当编译器添加更多功能时,对C++14以上版本的测试应该能够正常工作。如上所述,GCC使用201500L。看起来clang使用了201406L(我想是在C++14之后的四个月)。

使用上面的代码片段应该是跨平台的,即使C++17为__cplusplus带来了真正的价值,它也能工作。有关功能发展的更多详细信息,请尝试功能测试宏。

通常应该使用__cplusplus定义来检测c++17,但默认情况下,microsoft编译器不会正确定义该宏,请参阅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

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

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

要使其正确报告,还必须设置/Zc:__cplusplus

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

至于为什么?好用他们的话说:

我们尝试在默认情况下更新宏,发现当我们更改的值时,代码无法正确编译__cplusplus。

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

我真的不知道为什么__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

我会检查它是否是>= 201500,而不是检查任何特定的值。

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

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