【问题标题】:[[(un)likely]] attributes and do-while loops[[(un)likely]] 属性和 do-while 循环
【发布时间】:2022-07-20 03:37:46
【问题描述】:

简短说明:是否有放置[[(un)likely]] 属性的地方,以便cond2 处的控制流被认为可能采取错误分支,而不影响cond1 处分支的可能性 em>?

if (cond1) {
  do {
    foo();
  } while (cond2);
}

如果我把[[unlikely]]放在do [[unlikely]] {do { [[unlikely]]中,会影响cond1吗? 因为cond1的真分支是进入循环的ONLY路径并且是 ALWAYS 进入循环的路径,根据cppreference.com:

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

cond1 似乎受到了影响。

如果我将[[likely]] 放在循环之后,例如do { foo(); } while(cond2); [[likely]];,属性应用于空语句。此代码不直观,并且不清楚cond2 和/或cond1 是否受到影响。

顺便说一句,问题实际上是询问[[(un)likely]] 属性的语义,而不是关于实现,也不是__builtin_expect 之类的替代方案,或者将do-while 循环中断为foo(); while(cond2) [[unlikely]] foo();

【问题讨论】:

  • do { foo(); } while(cond2) [[likely]]; 有什么问题?
  • @GoswinvonBrederlow 无法编译。
  • 似乎唯一的解决方法是定义一个类似于__builtin_expect 的函数,例如inline bool unlikely_cond(bool cond) { if (cond) [[unlikely]] { return true; } else { return false; } },然后使用unlikely_cond(cond2)。但是我还是不明白[[(un)likely]]属性的exact语义。

标签: c++ c++20 likely-unlikely


【解决方案1】:

不是解决方案,但作为替代方案,可以尝试以下方法:

while (1){
    foo();
    if (cond2) [[unlikely]]
        break;
}

【讨论】:

    【解决方案2】:

    我相信这是属性的正确放置:

    if (cond1) [[likely]] {
        do [[unlikely]] {
            foo();
        } while (cond2);
    }
    

    这些属性只是显示每个放置位置的示例。 likely 影响ifunlikely 影响do/while。令人困惑的是,该属性与条件相去甚远,但这似乎是它编译的地方。

    【讨论】:

    • 但它强制 cond1 的真正分支成为可能,OP 希望避免这种情况。它仍然存在第二个属性如何表现的问题。
    • 详细说明属性只是示例。更好?
    猜你喜欢
    • 2022-12-01
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 2021-07-01
    • 2011-04-07
    • 2018-05-09
    • 1970-01-01
    • 2016-02-21
    相关资源
    最近更新 更多