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

Lee*_*hai 15 c++ gcc-warning c++20

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

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

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

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

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

use*_*670 10

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

if (a>b) [[likely]] {
Run Code Online (Sandbox Code Playgroud)

10.6.6似然属性[dcl.attr.likelihood]草案


Gab*_*ini 7

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

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

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

if (condition) { [[likely]] ... } else { ... }
Run Code Online (Sandbox Code Playgroud)

例如,当使用/std:c++latest.


pax*_*blo 5

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

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

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

    return 3;
}
Run Code Online (Sandbox Code Playgroud)

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


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

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

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

  • 如果我们可以在 if 语句中指定属性:“if ([[likely]]”,那么基于“__builtin_expect”移植现有代码会容易得多,例如“if (likely(a>b)) {” a>b) {`. (15认同)