如何在 if-else 语句中使用 C++20 的 likely/unlikely 属性

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

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

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

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

"warning: attributes at the beginning of statement are ignored [-Wattributes]".

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

基于 Jacksonville’18 ISO C++ Report 中的示例,语法正确,但似乎尚未实现:

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

10.6.6 Likelihood attributes [dcl.attr.likelihood] draft

So how should I use these attributes in an if-else statement?

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

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

    return 3;
}

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


你应该明白,除非最新草案和最终产品之间的某些措辞发生变化,即使兼容实现也能够忽略这些属性。它们是对编译器的建议,就像 C 中的 inline。来自最新的草案 n4762(在回答这个问题时,我强调) :

Note: The use of the likely attribute is intended to allow implementations to optimize for the case where paths of execution including it are arbitrarily more likely than any alternative path of execution that does not include such an attribute on a statement or label.

注意单词 "allow" 而不是 "force"、"require" 或 "mandate"。

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

Applies to a statement to allow the compiler to optimize for the case where paths of execution including that statement are more likely than any alternative path of execution that does not include such a statement.

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

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

此语法被接受,例如,Visual Studio 2019 16.7.0 在使用 /std:c++latest.

编译时