简体   繁体   English

__cplusplus 对 C++17 的价值是什么?

[英]What is the value of __cplusplus for C++17?

We are trying to test some code under C++17 and its change to std::uncaught_exception .我们正在尝试在 C++17 下测试一些代码及其std::uncaught_exception更改 I can't seem to get GCC to provide the value of __cplusplus :我似乎无法让 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
$

And:并且:

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

What is the value of __cplusplus when using C++17?使用 C++17 时__cplusplus的值是什么?

tl;dr: For C++17, __cplusplus is 201703L . tl;dr:对于 C++17, __cplusplus201703L

What is the value of __cplusplus when using C++17?使用 C++17 时__cplusplus的值是什么?

According to the draft standard N4594 §16.8/p1 Predefined macro names [cpp.predefined] ( Emphasis Mine ):根据草案标准N4594 §16.8/p1 预定义宏名称 [cpp.predefined]强调我的):

The following macro names shall be defined by the implementation: __cplusplus The name __cplusplus is defined to the value 201402L when compiling a C++ translation unit.以下宏名称应由实现定义: __cplusplus编译 C++ 翻译单元时,名称__cplusplus定义为值201402L 156 156

156) It is intended that future versions of this standard will replace the value of this macro with a greater value. 156) 本标准的未来版本打算用更大的值替换此宏的值。 Non-conforming compilers should use a value with at most five decimal digits.不符合标准的编译器应使用最多五位十进制数字的值。

However the same value is appointed for the C++14 standard.但是,为 C++14 标准指定了相同的值。 Apparently it seems so, that there's no official/standard __cplusplus value set yet for the C++17 standard.显然,C++17 标准还没有官方/标准的__cplusplus值集。

In GCC versions 6.1 and 7.0 the value is changed to 201500在 GCC 版本 6.1 和 7.0 中,该值更改为201500

Live Demo现场演示

In Clang version 3.8 and 3.9 the value is unchanged 201406 .在 Clang 版本 3.8 和 3.9 中,该值保持不变201406

Consequently, you'll have to wait a little bit for the standard value to come out.因此,您必须稍等片刻才能得出标准值。

--- Update --- --- 更新 ---

According to the C++ standard §19.8/p1 Predefined macro names [cpp.predefined] ( Emphasis Mine ):根据 C++ 标准§19.8/p1 预定义宏名称 [cpp.predefined] ( Emphasis Mine ):

1 The following macro names shall be defined by the implementation: 1以下宏名称应由实现定义:

__cplusplus The integer literal 201703L . __cplusplus整数文字201703L

Thus, the value of __cplusplus when using C++17 shall be 201703L .因此,使用 C++17 时__cplusplus的值应为201703L

I would try:我会尝试:

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

In other words, testing for greater than C++14 should work as compilers add more features.换句话说,当编译器添加更多功能时,测试大于 C++14 应该可以工作。 As someone mentioned above, GCC uses 201500L .正如上面提到的,GCC 使用201500L It looks like clang uses 201406L (four months after C++14 I guess).看起来 clang 使用201406L (我猜是在 C++14 之后四个月)。

Using the above snippet should be cross-platform and will work even when C++17 comes out with real value for __cplusplus .使用上面的代码片段应该是跨平台的,即使 C++17 为__cplusplus提供真正的价值也能工作。 For more details about evolving features try the feature test macros .有关不断发展的功能的更多详细信息,请尝试功能测试宏

Normally you should use __cplusplus define to detect c++17, but by default microsoft compiler does not define that macro properly, see https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - you need to either modify project settings to include /Zc:__cplusplus switch, or you could use syntax like this:通常你应该使用__cplusplus定义来检测 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

I realize you asked this question citing the Gnu C++ compiler as the one you're using, but you may want to have some awareness of what happens on the Visual C++ compiler, and strictly speaking, your question didn't ask about a specific compiler.我意识到你问这个问题时引用了 Gnu C++ 编译器作为你正在使用的编译器,但你可能想了解 Visual C++ 编译器上发生的事情,严格来说,你的问题没有询问特定的编译器.

Currently, as of the date of this posting, the VC++ 2017 compiler sets __cplusplus to 199711L rather than what you might expect if you set the compiler to use c++17.目前,截至本文发布之日,VC++ 2017 编译器将__cplusplus设置为199711L而不是将编译器设置为使用 c++17 时所期望的值。

To get it to report correctly, you have to also set /Zc:__cplusplus .要使其正确报告,您还必须设置/Zc:__cplusplus

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

As to why?至于为什么? Well... in their words:嗯……用他们的话来说:

We tried updating the macro by default and discovered that a lot of code doesn't compile correctly when we change the value of __cplusplus.我们尝试默认更新宏,发现当我们更改 __cplusplus 的值时,很多代码无法正确编译。

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

I don't really know why __cplusplus doesn't show up as a regular macro, but I'm guessing it's so you can't redefine it.我真的不知道为什么__cplusplus没有显示为常规宏,但我猜是这样你不能重新定义它。 This is how I determine the its value.这就是我确定它的价值的方式。

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

Then compilation shows the value.然后编译显示值。

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

I would check whether it's >= 201500 as opposed to checking for any specific value.我会检查它是否>= 201500 ,而不是检查任何特定值。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM