简体   繁体   English

Visual Studio 2012 __cplusplus 和 C++ 11

[英]Visual Studio 2012 __cplusplus and C++ 11

Anyone know why __cplusplus is defined as 199711L (which is the "old" C++) in my Visual Studio 2012 c++ project?任何人都知道为什么__cplusplus在我的 Visual Studio 2012 c++ 项目中被定义为199711L (这是“旧”C++)? Should it not say 201103L since VS 2012 now has C++ 11 support?自从VS 2012现在支持C ++ 11以来,不应该说201103L吗? Even if I include C++ 11 headers it still is wrongly defined.即使我包含 C++ 11 头文件,它仍然是错误定义的。 Any clues?有什么线索吗?

This has already been submitted to Microsoft for review:这已提交给 Microsoft 进行审核:

A value of predefined macro __cplusplus is still 199711L 预定义宏 __cplusplus 的值仍然是 199711L

It really depends on what you expect that macro to actually mean.这实际上取决于您期望该宏的实际含义。 Should 201103L mean "This compiler fully supports all of C++11 in both the compiler and the library?" 201103L 是否应该表示“此编译器完全支持编译器和库中的所有 C++11?” Should it mean "This compiler supports some reasonable subset of C++11?"它应该意味着“这个编译器支持一些合理的 C++11 子集吗?” Should it mean "This compiler supports at least one C++11 feature in some way, shape, or form?"是否应该表示“此编译器以某种方式、形状或形式支持至少一个C++11 功能?”

It's really up to each implementation to decide when to bump the version number.真正取决于每个实现来决定何时增加版本号。 Visual Studio is different from Clang and GCC, as it has no separate C++03 compilation mode; Visual Studio 与 Clang 和 GCC 不同,它没有单独的 C++03 编译模式; it provides a specific set of features, and that's what it provides.它提供了一组特定的功能,这就是它所提供的。

In general, a single macro is not a useful tool to decide when to use some feature.通常,单个宏不是决定何时使用某些功能的有用工具。 Boost.Config is a far more reliable mechanism. Boost.Config是一种更可靠的机制。 The standards committee is investigating ways of dealing with this problem in future versions of the standard.标准委员会正在研究在标准的未来版本中处理这个问题的方法

I am with Nicol on this one.我和尼科尔在这件事上。 The only reason to test for __cplusplus >= 201103L is to check whether you can use the new features.测试__cplusplus >= 201103L的唯一原因是检查您是否可以使用新功能。 If a compiler implements only half of the new features but uses the new value of __cplusplus , it will fail to compile a lot of valid C++11 code protected by __cplusplus >= 201103L (I have some that uses thread_local and *this references).如果编译器只实现了一半的新特性但使用__cplusplus的新值,它将无法编译许多受__cplusplus >= 201103L保护的有效 C++11 代码(我有一些使用thread_local*this引用) . If on the other hand it keeps 199711L , it will use the safe C++98 code, which is still fine.另一方面,如果它保留199711L ,它将使用安全的 C++98 代码,这仍然可以。 It may miss a few optimizations that way, but you can still use other ways to detect if a specific feature is available (compiler version, compiler specific macros like __GXX_EXPERIMENTAL_CXX0X__ , boost macros that check compiler macros for you, etc).这样可能会错过一些优化,但您仍然可以使用其他方法来检测特定功能是否可用(编译器版本、编译器特定宏,如__GXX_EXPERIMENTAL_CXX0X__ 、为您检查编译器宏的 boost 宏等)。 What matters is a safe default.重要的是安全的默认值。

There are 2 possible reasons to switch to the new value of __cplusplus:切换到 __cplusplus 的新值有 2 个可能的原因:

  • your compiler has full support for C++11 (or close enough, there will always be bugs)您的编译器完全支持 C++11(或足够接近,总会有错误)
  • this is an experimental mode of your compiler that shouldn't be used in production, and what would normally be missing features count as bugs.这是编译器的实验模式,不应在生产中使用,通常缺少的功能会被视为错误。

As far as I know, all compilers that have switched are in the second category.据我所知,所有切换的编译器都属于第二类。

I believe some compiler vendors have been way too enthusiastic about changing the value of __cplusplus (easiest C++11 feature to implement, good publicity), and it is good that some are more conservative.我相信一些编译器供应商对改变 __cplusplus 的值(最容易实现的 C++11 特性,良好的宣传)过于热情,而且有些更保守是好的。

As of April 2018 MSVC 2017 now correctlys reports the macro, but only if a specific switch is used ( /Zc:__cplusplus ).截至 2018 年 4 月,MSVC 2017 现在可以正确报告宏,但前提是使用特定开关 ( /Zc:__cplusplus )。 This is because a lot of old code relies on detecting the old value of the macro for MSVC compilers.这是因为许多旧代码依赖于检测 MSVC 编译器的宏的旧值。 Source 资源

Hopefully in future, once people worldwide have updated their code, MS will report the macro correctly by default.希望将来,一旦全世界的人们更新了他们的代码,MS 将默认正确报告宏。

As pointed out in another answer, /Zc:__cplusplus is pretty much the answer.正如另一个答案中所指出的, /Zc:__cplusplus几乎就是答案。 Suppose you have a bunch of .vcxproj files underneath a folder hierarchy, simply place a file named Directory.Build.props into the common parent folder and populate it as follows:假设您在文件夹层次结构下有一堆.vcxproj文件,只需将名为Directory.Build.props的文件放入公共父文件夹并按如下方式填充它:

<?xml version="1.0" encoding="utf-8"?>
<Project>
  <ItemDefinitionGroup>
    <ClCompile>
      <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
    </ClCompile>
  </ItemDefinitionGroup>
</Project>

You could also use your very own user property sheets to set this there.您也可以使用您自己的用户属性表在此处进行设置。 Ie in %LOCALAPPDATA%\Local\Microsoft\MSBuild\v4.0 inside all of the Microsoft.Cpp.*.user.props files (where * is the placeholder for the target platforms).即在所有Microsoft.Cpp.*.user.props文件中的%LOCALAPPDATA%\Local\Microsoft\MSBuild\v4.0中(其中*是目标平台的占位符)。

Furthermore it is probably sensible to be defensive about this in code, which means resorting to checking for both _MSVC_LANG and __cplusplus like so (or similar):此外,在代码中__cplusplus这样_MSVC_LANG或类似):

#if defined(__cplusplus) && defined(_MSVC_LANG) && (__cplusplus == 199711L)
// Check against _MSVC_LANG with the value you expect for __cplusplus
#else
// Check against __cplusplus as usual
#endif

I would recommend using something like this whenever you can't be certain that your code (eg a header, because you are a library author) is used while /Zc:__cplusplus was specified on the command line.我建议在您无法确定在命令行上指定/Zc:__cplusplus使用了您的代码(例如,标题,因为您是库作者)时使用类似的东西。

I'm still a bit puzzled why this is still the case as of VS2022, because if you look at C++ compiler support , Visual C++ isn't half bad compared to all the others.我仍然有点困惑,为什么在 VS2022 中仍然如此,因为如果您查看C++ 编译器支持,Visual C++ 与所有其他的相比还不错。

All the above said, you may want to use feature test macros instead of testing for the C++ standard version.综上所述,您可能希望使用功能测试宏而不是测试 C++ 标准版本。

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

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