我正在寻找设置一些预处理器的东西,并且我想要一个更准确的数字来说明 C++14 中的
__cplusplus
应该定义为什么。标准中有规定吗?
cppreference 在“
预定义宏”部分中提供了有关
__cplusplus
宏标准值的信息。目前的标准值为:
199711L
(C++98 或 C++03)201103L
(C++11)201402L
(C++14)201703L
(C++17)202002L
(C++20)202302L
(C++23)在最终标准发布之前,宏对于任何给定版本的价值都尚未确定。因此,截至 2019 年 6 月,无法知道 C++2a 的宏值是什么(截至 2021 年 2 月,无法知道 C++2b 的宏值是什么)。
库供应商通常在
#if __cplusplus > 201703L
上门控他们的“C++2a”功能,在 __cplusplus > 202002L
上门控他们的“C++2b”功能,等等。
具有“C++2a”模式的编译器供应商只需为
__cplusplus
选择任意值,这会让库供应商的检查满意:
GCC(8.x 至 10.x)
-std=c++2a
模式使用 __cplusplus == 201709L
。-std=c++2a
模式使用 __cplusplus == 201707L
。/std:c++latest
模式使用 __cplusplus == 201705L
当且仅当您通过 /Zc:__cplusplus
!否则它使用 199711L
。所以要小心!
Clang 4.0.1
-std=c++1z
设置__cplusplus == 201406L
。 Clang 5.0.0 引入了 -std=c++17
和 -std=c++2a
,使 -std=c++1z
成为 -std=c++17
的同义词,并将宏(无论您使用 17
/1z
中的哪一个)提升到标准值 201703L
。 Clang 10.0 引入了 -std=c++20
,使 -std=c++2a
成为 -std=c++20
的同义词,并将宏提升到标准值 202002L
。截至 2021 年 2 月,Clang 还没有正式的“C++2b”模式。
GCC 5.1 引入了
-std=c++1z
和 -std=c++17
作为同义词,设置了 __cplusplus == 201500L
。 GCC 7.1 将值(无论您使用哪种拼写)提高到标准值 201703L
。 GCC 8.1 引入了 -std=c++2a
和 __cplusplus == 201709L
。 GCC 10.1 引入了 -std=c++20
作为 -std=c++2a
的同义词(但将宏保留为 201709L
)。截至 2021 年 2 月,GCC 主干已引入 -std=c++2b
和 __cplusplus == 202100L
。
奇怪的是,根据 Godbolt Compiler Explorer 的说法,MSVC 在 MSVC 19.16 和 19.20 之间的某个时间将
-std:c++latest
模式的宏从 201704L
更改为 201705L
。截至2021年2月,据我所知,MSVC还没有正式的“C++20”模式。
N3936* §16.8 [cpp.预定义]/p1:
1 以下宏名称应由实现定义:
__cplusplus
名称
被定义为值__cplusplus
,当 编译 C++ 翻译单元。201402L
N3936 是成为 C++14 的最终工作草案,编号
201402L
与 C++14 标准发出进行最终投票的会议一致(2014 年 2 月)。
*那些有兴趣获取 C++ 标准副本的人应该查看 在哪里可以找到当前的 C 或 C++ 标准文档?