C++的“特性测试宏”代表什么意思?

7
要测试一个特性,cppreference提到了这些特性测试宏:链接。如果编译器支持该特性,则定义了宏。但是我不明白为什么如果被定义了,它们会被定义为像201606这样的东西,我认为这是C++的一个版本,而不是编译器的版本。例如,我正在使用带有-std=c++17的最新版本GCC来使用__cpp_lib_hardware_interference_size特性。该宏未定义,我想这意味着GCC没有此特性,尽管我已经使用c++17(和c++2a)开关尝试了8.2.1。在这种情况下,文档中记录的值的意义是什么:__cpp_lib_hardware_interference_size 201703(在cppreference链接内部)?

1
在我看来,这只是为了未来的保障,以便如果某个功能被认为不完整并需要在标准的未来版本中进行更新,可以区分更新前和更新后。 - user4442671
1
另外,顺便提一下,这是C++的一个版本(而不是编译器的版本),因为这些特性是C++标准的一部分,因此符合C++ X版的任何编译器都将具有这些特性。也就是说,功能支持取决于C++版本,而不是编译器版本(当然,随着编译器增加支持,其版本往往会增加,但语言版本才是真正的关键)。 - Jason C
2个回答

10
根据cppreference.com,它说:
以下宏扩展为与功能包含在工作草案中的年份和月份对应的数字值。
当功能发生重大更改时,相应的宏将被更新。
因此,您可以通过检查宏是否被定义来检查功能是否存在。或者,您可以基于宏值检查功能版本。

-1
我同意你的观点,feature_test 的描述方式确实不够好。在这种情况下,最好使用语言标准。虽然它们并不是免费公开的,但有一些工作草案可供参考:
  • [1] C++2017 草案。文档编号:N4659 / 日期:2017-03-21 / 修订版本:N4640. link

  • [2] C++2020 草案。文档编号:N4861 / 日期:2020-04-01 / 修订版本:N4849. link

(草案链接可能在10年后过期,但我已提供文档名称以遵守 StackOverflow 政策。)


例如,我正在使用带有-std=c++17的最新版本GCC来使用特性__cpp_lib_hardware_interference_size。宏未定义,这意味着GCC没有该特性...
并不完全准确。我们要小心。这个内联constexpr常量可以从C++2017中获取hardware_destructive_interference_size,但问题是在C++2020中才引入了使用__cpp_*进行功能测试 feature_test 的能力。你在[1]中找不到任何__cpp_*宏定义。不支持的是通过功能测试宏自身测试功能的能力,而不是GCC工具链中C++2017的功能。

为了测试一个特性,cppreference提到了这些特性测试宏...

如果支持功能测试,则可以测试该特性。它仅从C++2020开始得到支持(正式支持)。
在所有版本的C/C++中,编译器保留了以下名称:
  • 以双下划线 __ 开头
  • 下划线 _ 后跟大写字母的名称。

你可以在 C++98/03/11/14/17 中尝试使用这个机制,但宏可能未定义,在 #if 语句中,未定义的宏将会展开为 0 值。

但这是非常不可靠的。

它们被定义为类似 201606 的内容,我相信这是 C++ 的一个版本,而不是编译器的版本...

请小心。第 15.11 节 [2] 并没有明确说明这一点。然而,我希望工具链的实现能够准确定义你所说的。不幸的是,(草案版的)标准并没有强制要求。


亲爱的@J. Calleja,
所以,你可以通过检查宏是否定义来检查该功能是否存在。
是的,但如果你使用的是C++2020,而不是C++98/03/11/14/17。
或者你可以根据宏值来检查功能版本。
我想再添加一条额外的评论。请注意[2]第15.11节第455页中的以下声明:
"未来版本的国际标准可能会用更大的值替换这些宏的值。"
我没有看到cppreference feature_test中提到这一点的任何内容。
如果你想生成兼容的代码,请使用如下结构:
#if __cpp_char8_t >= 201811L
///
#endif

这个问题被标记为gcc。C++标准中没有错误,libstdc++也没有错误。一切都按预期工作,你对这个特性在C++20中引入到libstdc++实现中的影响的解释是不正确的。 - ComicSansMS
我明白了。你能提供一个参考资料,让我了解这个是在之前引入的吗?因为根据这个链接 - https://en.cppreference.com/w/cpp/feature_test "Feature testing (since C++20)" - Konstantin Burlachenko
@ComicSansMS 我提供了两份文件,证明这个库特性只出现在C++20中,你能提供一些你方面的资料吗?我很乐意学习,但你没有提供任何信息来源。 - Konstantin Burlachenko
我在我的第一条评论中提供了材料。你的回答仍然暗示问题中使用-std=c++17是有重要意义的,这是误导性的。接受的答案唯一没有提到的是libstdc++只从9.2版本开始逐步引入这些宏,这解释了为什么问题中的设置将该宏定义为未定义。虽然你所写的在技术上是正确的,但我觉得在这个问题的背景下是不相关的,因为这个问题的核心是关于如果宏被定义了,它会有什么含义。 - ComicSansMS
您提供了GCC源代码的链接,非常棒。但是C++语言的定义不是由GCC(C++编译器和C++标准库)定义的,而是由C++标准定义的。 - Konstantin Burlachenko
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接