微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 `switch` 语句中正确使用 C++20 `[likely]]`/`[[unlikely]]`

如何解决在 `switch` 语句中正确使用 C++20 `[likely]]`/`[[unlikely]]`

C++20 具有指导代码生成的方便的 [[likely]]/[[unlikely]] 属性。例如,您可以指定一个分支可能被采用:

if (b) [[likely]] { /*...*/ }

同样,可以在 switch 语句中使用这些属性。 . .不知何故? The documentation 建议使用以下示例(稍微格式化):

switch (i) {
    case 1:
        [[fallthrough]];
    [[likely]] case 2:
        return 1;
}

这显然意味着 [[likely]]/[[unlikely]]case 语句之前。互联网似乎几乎普遍宣扬这种用法

但是,请考虑以下类似的代码(我所做的只是将 [[likely]] 移动到另一个 case):

switch (i) {
    [[likely]] case 1:
        [[fallthrough]];
    case 2:
        return 1;
}

这无法在 clang 上编译!虽然这可能与 a compiler bug with [[fallthrough]] 有关,但它让我关注了标准。 relevant standard 具有以下示例(参见 §VII):

鼓励实现针对正在执行的案例进行优化(例如,以下代码中的值为 1):

switch (a) {
    case 1: [[likely]]
        foo();
        break;
    //...
}

也就是说,属性出现在案例标签之后,而不是之前。

所以。 . .它是哪个?顺便说一句,我希望标准是正确的,但这实际上是一个提案,而不是真正的标准 AFAICT——它可能已经改变了。而且,我希望文档至少在基本语法方面是正确的——除了它甚至无法编译。

解决方法

两个示例都是有效的,并且 Clang 出现了一个错误。 C++20 最新标准草案中的相关措辞是

[dcl.attr.likelihood]

1 属性标记 likelyunlikely 可应用于标签或语句。

语句和标记语句的相关语法产生式在适当位置具有属性说明符序列。

[stmt.pre]

statement:
  labeled-statement
  attribute-specifier-seq expression-statement
  attribute-specifier-seq compound-statement
  attribute-specifier-seq selection-statement
  attribute-specifier-seq iteration-statement
  attribute-specifier-seq jump-statement
  declaration-statement
  attribute-specifier-seq try-block

[stmt.label]

labeled-statement:
  attribute-specifier-seq identifier : statement
  attribute-specifier-seq case constant-expression : statement
  attribute-specifier-seq default : statement

switch (i) {
    case 1:
        [[fallthrough]];
    [[likely]] case 2:
        return 1;
}

该属性适用于 case 2:

switch (a) {
    case 1: [[likely]]
        foo();
        break;
    //...
}

它适用于语句 foo();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?