21

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

4

4 回答 4

16

这已提交给 Microsoft 进行审核:

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

于 2013-01-03T00:40:16.860 回答
8

这实际上取决于您期望该宏的实际含义。201103L 是否应该表示“此编译器完全支持编译器和库中的所有 C++11?” 它应该意味着“这个编译器支持一些合理的 C++11 子集吗?” 是否应该表示“此编译器以某种方式、形状或形式支持至少一个C++11 功能?”

真正取决于每个实现来决定何时增加版本号。Visual Studio 与 Clang 和 GCC 不同,它没有单独的 C++03 编译模式;它提供了一组特定的功能,这就是它所提供的。

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

于 2013-01-03T00:46:23.453 回答
4

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

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

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

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

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

于 2013-01-06T13:45:28.410 回答
3

截至 2018 年 4 月,MSVC 2017 现在可以正确报告宏,但前提是使用特定开关 (/Zc:__cplusplus)。这是因为许多旧代码依赖于检测 MSVC 编译器的宏的旧值。来源:https ://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/

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

于 2018-07-12T10:22:57.987 回答