如何确定编译器使用的C ++标准版本?


114

您如何确定编译器实现了哪个版本的C ++标准?据我所知,以下是我所知道的标准:

  • C ++ 03
  • C ++ 98

3
您标记了此c ++,但是列出的三个标准中的两个不是C ++标准。您对哪种语言感兴趣?
罗伯·肯尼迪

1
几分钟前才问过这个问题。(stackoverflow.com/questions/7132440/...

1
@Mat:因为问题是垃圾,还带着其他一些胡说八道,所以摆姿势并关闭了。我以体面的形式重新发布了它。如果看起来像原件将被修复并恢复原样,我将很乐意将其关闭,但我没有屏息。
Lightness Races in Orbit

1
@Mat:嗯,最好的答案不是静态的编译器列表,而是自己确定正在使用什么的方法。所以你去了。
在轨道进行的轻度比赛

1
@Als:很快。我承诺。此外,c++-faq标签没有必须通过的任何实际的前提条件“要求的次数”;它更多地是关于事物的格式和一般性。
Lightness Races in Orbit

Answers:


13

据我所知,没有整体方法可以做到这一点。如果您查看跨平台/多个编译器支持库的标头,您将总会发现许多使用编译器特定的结构来确定此类内容的定义:

/*Define Microsoft Visual C++ .NET (32-bit) compiler */
#if (defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER >= 1300)
     ...
#endif

/*Define Borland 5.0 C++ (16-bit) compiler */
#if defined(__BORLANDC__) && !defined(__WIN32__)
     ...
#endif

您可能必须为使用的所有编译器自己进行这样的定义。


1
虽然这不是我期望的答案,但我想还没有找到答案的通用方法。
jasonline

246

来自Bjarne Stroustrup C ++ 0x常见问题解答

__cplusplus

在C ++ 0x中,宏__cplusplus将被设置为不同于(大于)current的值199711L

尽管这并不像人们希望的那样有用。gcc(显然是将近10年)将此值设置为1,排除了一个主要的编译器,直到在gcc 4.7.0出现时被固定

这些是C ++标准,您应该期望得到什么价值__cplusplus

  • C ++ C-98之前的版本:__cplusplus1
  • C ++ 98:__cplusplus199711L
  • C ++ 98 + TR1:读为C ++ 98,无法检查我是否知道。
  • C ++ 11:__cplusplus201103L
  • C ++ 14:__cplusplus201402L
  • C ++ 17:__cplusplus201703L

如果编译器可能较旧gcc,则需要诉诸于编译器特定的黑客(查看版本宏,将其与具有已实现功能的表进行比较)或使用Boost.Config(提供相关宏))。这样做的好处是我们实际上可以选择新标准的特定功能,如果缺少该功能,则可以编写解决方法。这通常比批发解决方案更可取,因为某些编译器会声称实现C ++ 11,但仅提供部分功能。

Stdcxx Wiki拥有用于C ++ 0x功能的编译器支持的全面矩阵(如果您敢亲自检查这些功能)。

不幸的是,std::copy_if只能在您的应用程序的构建系统中进行更细粒度的功能检查(例如像单个库功能)(运行带有该功能的代码,检查其是否编译并产生正确的结果- autoconf如果采用这条路线)。


看起来好像编译器供应商没有更新它-也许他们正在等待直到完全符合标准?(stackoverflow.com/q/14131454/11698
Richard Corden

2
@prnr:可能是正确的,但这取决于提出问题的用户来决定接受哪个答案。在发布当前标记为已接受的答案时,它是正确的,因此原始张贴者已接受它。该用户可以决定更改接受的答案,但是他们可能不再在该站点上处于活动状态。请参阅:meta.stackexchange.com/questions/120568/...
丹科恩

3
vs2017提供__cplusplus的值199711
Al Mamun

5
@AlMamun Microsoft __cplusplus仅在VS 15.7中得到部分修复。请参阅他们的Visual C ++团队博客
Ivan_Bereziuk

1
常见问题解答的链接已损坏。
brainplot '19

38

请运行以下代码以检查版本。

#include<iostream>

int main() {
    if (__cplusplus == 201703L) std::cout << "C++17\n";
    else if (__cplusplus == 201402L) std::cout << "C++14\n";
    else if (__cplusplus == 201103L) std::cout << "C++11\n";
    else if (__cplusplus == 199711L) std::cout << "C++98\n";
    else std::cout << "pre-standard C++\n";
}

8
这很有趣,因为在视觉工作室中__cplusplus的值为199711L,而您发布的代码返回了c ++ 98,但是,我使用了c ++ 14中的功能,包括变量模板和decltype(auto)。是否可能实施了错误的宏版本?
Colin Hicks

2
请参阅:devblogs.microsoft.com/cppblog/…(TLDR:指定标志/Zc:__cplusplus
Daan Timmer

@DaanTimmer我对那篇文章感到困惑,它似乎假设您已经知道如何使用该/Zc:__cplusplus标志。我不能简单地std::cout << /Zc:__cplusplus;因为冒号和斜杠当然不能成为变量名的一部分。您能解释如何执行此操作吗?谢谢。
A__


7

根据您要实现的目标,Boost.Config可能会为您提供帮助。它不提供对标准版本的检测,但是提供了宏,可让您检查对特定语言/编译器功能的支持。


3
无论如何,检查功能可能比检查标准版本更好。很少有编译器支持一切从标准,但如果它们都支持的功能数量有限,需要的话,就没有真正的问题是否的功能从给定的标准,其余均实现并正常工作。
罗伯·肯尼迪



0

经过一个快速谷歌

__STDC__并且__STDC_VERSION__,请看这里


是否__STDC__定义以及其值由C ++实现定义。
罗伯·肯尼迪

@Rob:是的。@Tor:我在VC ++ 2005中尝试过,但是它说STDC是一个未声明的标识符。但是,它被列为那些预定义的宏之一。但是,STDC_VERSION不存在。
jasonline'2

这告诉您编译器支持的C编程语言的版本。它没有告诉您有关所支持的C ++语言版本的任何信息。
丹·

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.