41

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

本文档 ( cppreference ) 仅给出了将它们应用于 switch-case 语句的示例。这个 switch-case 示例与我的编译器 (g++-7.2) 完美编译,所以我假设编译器已经实现了这个特性,尽管它还没有在当前的 C++ 标准中正式引入。

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

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

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

4

3 回答 3

20

根据Jacksonville'18 ISO C++ Report中的示例,语法是正确的,但似乎尚未实现:

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

10.6.6 可能性属性 [dcl.attr.likelihood]草稿

于 2018-08-11T08:51:59.777 回答
6

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

应用于语句以允许编译器针对包含该语句的执行路径比不包含此类语句的任何替代执行路径更有可能的情况进行优化

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

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

例如,Visual Studio 2019 16.7.0 在使用/std:c++latest.

于 2020-07-25T22:40:09.550 回答
4

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

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

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

    return 3;
}

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


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

注意: 使用可能属性的目的是允许实现优化包含它的执行路径比不包括语句或标签上的此类属性的任何替代执行路径任意更有可能的情况。

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

于 2018-08-11T09:33:50.003 回答