Visual Studio 2012 __cplusplus和C++ 11

18 c++ visual-studio visual-c++ c++11

任何人都知道为什么在我的Visual Studio 2012 c ++项目中__cplusplus定义为199711L(这是"旧的"C++)?不应该说,201103L因为VS 2012现在有C++ 11支持吗?即使我包含C++ 11标头,它仍然是错误定义的.有线索吗?

Rem*_*eau 14

这已经提交给Microsoft进行审核:

预定义的宏__cplusplus的值仍然是199711L


Nic*_*las 7

这实际上取决于你对宏的实际意义.201103L应该是"这个编译器完全支持编译器和库中的所有C++ 11吗?" 它应该意味着"这个编译器支持一些合理的C++ 11子集吗?" 它应该意味着"这个编译器以某种方式,形状或形式支持至少一个 C++ 11特性?"

每个实现都要决定何时推出版本号.Visual Studio与Clang和GCC不同,因为它没有单独的C++ 03编译模式; 它提供了一组特定的功能,这就是它提供的功能.

通常,单个宏不是决定何时使用某些功能的有用工具.Boost.Config是一种更可靠的机制.标准委员会正在研究在未来版本的标准中处理这个问题的方法.


Mar*_*sse 5

在这一点上我和尼科尔是一致的。测试的唯一原因__cplusplus >= 201103L是检查您是否可以使用新功能。如果编译器只实现了一半的新功能但使用了新值,它将无法编译受(我有一些使用和引用)__cplusplus保护的许多有效C++11代码。另一方面,如果它保留,它将使用安全的 C++98 代码,这仍然没问题。这样可能会错过一些优化,但您仍然可以使用其他方法来检测特定功能是否可用(编译器版本、编译器特定宏,如为您检查编译器宏的 boost 宏等)。重要的是安全的默认值。__cplusplus >= 201103Lthread_local*this199711L__GXX_EXPERIMENTAL_CXX0X__

切换到 __cplusplus 的新值有 2 个可能的原因:

  • 你的编译器完全支持 C++11(或者足够接近,总会有错误)
  • 这是编译器的实验模式,不应在生产中使用,通常缺少的功能将被视为错误。

据我所知,所有切换的编译器都属于第二类。

我相信一些编译器供应商对于改变 __cplusplus 的值(最容易实现的 C++11 功能,良好的宣传)过于热情,而且有些编译器供应商比较保守是好事。


met*_*sis 5

截至 2018 年 4 月,MSVC 2017 现在可以正确报告宏,但前提是使用特定开关 ( /Zc:__cplusplus)。这是因为许多旧代码依赖于检测 MSVC 编译器宏的旧值。 来源

希望将来,一旦全世界的人们更新了他们的代码,微软将默认正确地报告宏。