简体   繁体   English

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

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

This question is about C++20's [[likely]] / [[unlikely]] feature, not compiler-defined macros.这个问题是关于 C++20 的[[likely]] / [[unlikely]]特性,而不是编译器定义的宏。

This documents ( cppreference ) only gave an example on applying them to a switch-case statement.本文档 ( cppreference ) 仅给出了将它们应用于 switch-case 语句的示例。 This switch-case example compiles perfectly with my compiler (g++-7.2) so I assume the compiler has implemented this feature, though it's not yet officially introduced in current C++ standards.这个 switch-case 示例与我的编译器 (g++-7.2)完美编译,所以我假设编译器已经实现了这个特性,尽管它在当前的 C++ 标准中还没有正式引入。

But when I use them like this: if (condition) [[likely]] { ... } else { ... } , I got a warning:但是当我像这样使用它们时: if (condition) [[likely]] { ... } else { ... } ,我收到一个警告:

"warning: attributes at the beginning of statement are ignored [-Wattributes]". “警告:语句开头的属性被忽略 [-Wattributes]”。

So how should I use these attributes in an if-else statement?那么我应该如何在 if-else 语句中使用这些属性呢?

Based on example from Jacksonville'18 ISO C++ Report the syntax is correct, but it seems that it is not implemented yet:根据Jacksonville'18 ISO C++ Report的示例,语法是正确的,但似乎尚未实现:

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

10.6.6 Likelihood attributes [dcl.attr.likelihood] draft 10.6.6 可能性属性 [dcl.attr.likelihood]草案

So how should I use these attributes in an if-else statement?那么我应该如何在 if-else 语句中使用这些属性呢?

Exactly as you are doing, your syntax is correct as per the example given in the draft standard (simplified to show relevant bits only):正是因为你干什么,你的语法是按标准草案(简化为只显示相关的位)给出的示例中正确的是:

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

    return 3;
}

But you should understand that this feature is a relatively new one, so may only have placeholders in implementations to allow you to set the attributes.但是你应该明白这个特性是一个相对较新的特性,所以在实现中可能只有占位符来允许你设置属性。 This appears apparent from your warning message.这在您的警告消息中很明显。


You should also understand that, unless certain wording changes between the latest draft and the final product, even compliant implementations are able to ignore these attributes.应该了解,除非最新草案和最终产品之间的某些措辞发生变化,否则即使是合规的实现也能够忽略这些属性。 They are very much suggestions to the compiler, like inline in C. From that latest draft n4762 (at the time of this answer, and with my emphasis):它们对编译器有很多建议,比如在 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.注意:使用可能的属性旨在允许实现针对以下情况进行优化:包含它的执行路径比在语句或标签上不包含此类属性的任何替代执行路径更有可能。

Note the word "allow" rather than "force", "require" or "mandate".请注意“允许”一词,而不是“强制”、“要求”或“授权”。

As of today, cppreference states that, for example, likely (emphasis mine):截至今天, 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.应用于语句以允许编译器针对包含该语句的执行路径比不包含此类语句的任何替代执行路径更有可能的情况进行优化。

That suggests that the place to put the attribute is in the statement that is most likely, ie:这表明放置属性的位置是最有可能的语句,即:

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

This syntax is accepted, for example, by Visual Studio 2019 16.7.0 when compiling with /std:c++latest .例如,在使用/std:c++latest编译时,Visual Studio 2019 16.7.0 接受此语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM