如何在 if-else 语句中使用 C++20 的可能/不太可能属性

How to use C++20's likely/unlikely attribute in if-else statement

本文关键字:属性 C++20 if-else 语句      更新时间:2023-10-16

这个问题是关于C++20的[[likely]]/[[unlikely]]功能,而不是编译器定义的宏。

本文档(cpp首选项(仅给出了将它们应用于开关案例语句的示例。这个开关大小写示例与我的编译器 (g++-7.2( 完美编译,因此我假设编译器已经实现了此功能,尽管它尚未在当前的C++标准中正式引入。

但是当我像这样使用它们时:if (condition) [[likely]] { ... } else { ... },我收到了警告:

"警告:语句开头的属性将被忽略 [-Wattributes]"。

那么我应该如何在 if-else 语句中使用这些属性呢?

基于杰克逊维尔 18 ISO C++ 报告中的示例,语法是正确的,但似乎尚未实现:

if (a>b) [[likely]] {

10.6.6 似然属性[dcl.attr.似然]草稿

截至今天,cpppreferences指出,例如,likely(强调我的(:

应用于语句以允许编译器针对案例进行优化 包含该语句的执行路径更有可能超过 不包含此类 陈述。

这表明放置属性的位置在最有可能的语句中,即:

if (condition) { [[likely]] ... } else { ... }

例如,Visual Studio 2019 16.7.0 在使用/std:c++latest进行编译时接受此语法。

那么我应该如何在 if-else 语句中使用这些属性呢?

正如您所做的那样,根据标准草案中给出的示例,您的语法是正确的(简化为仅显示相关位(:

int f(int n) {
if (n > 5) [[unlikely]] {
g(0);
return n * 2 + 1;
}
return 3;
}

但您应该了解此功能是一个相对较新的功能,因此在实现中可能只有占位符以允许您设置属性。从您的警告消息中可以明显看出这一点。


应该了解,除非最新草案和最终产品之间的某些措辞发生变化,否则即使是合规的实现也可以忽略这些属性。它们是对编译器的建议,就像 C 语言中的inline一样。从最新的草案n4762(在回答这个答案时,并强调(:

注意:使用 possible 属性旨在允许实现针对以下情况进行优化:包含该属性的执行路径比语句或标签上不包含此类属性的任何替代执行路径更有可能

请注意"允许"一词,而不是"强制"、"要求"或"授权"。