【问题标题】:C - Function parameter as case in switch statementC - 函数参数作为 switch 语句中的 case
【发布时间】:2014-10-10 14:56:11
【问题描述】:

标题对谷歌来说有点太模糊了。

我发现自己计划多次编写这个 switch 语句,所以我想把它移到一个函数中。

我要做的是创建一个函数,该函数接受一个值、您期望的值以及该值的字符串标识符。

bool checkValue(int value, uint8_t expected, char * id) {
    switch (value) {
        case expected:
            return true;
        case -1:
            printf("Error: Timeout on %s\r\n", id);
        default:
            printf("Error: %s=%02x\r\n", id, value);
            return false;
    }
}

编译器抱怨case expected: 行上的“表达式必须有一个常量值”。现在,我知道我可以将其更改为一系列ifs,但我很感兴趣为什么这不起作用,或者是否有办法让它起作用。

switch 语句是否只是以无法将变量替换为 case 值的方式编译?

【问题讨论】:

  • 是的,case标签必须是常量表达式。
  • 不能在case表达式中使用变量!它必须保持不变!
  • 它不起作用,因为规范不允许。
  • 并且规范不允许这样做,因为它希望允许将 case 语句编译成比一系列条件分支更有效的实现。例如,基于跳转表的单个分支。 (一个特定的编译器实际上是否选择这样做是一个完全不同的问题。)
  • ...不要忽视expected == -1时的附加乐趣。

标签: c gcc switch-statement


【解决方案1】:

编译器错误几乎可以告诉您为什么它被禁止。它包含在 6.4.2 [stmt.switch] 中:

2 条件应为整型、枚举型或 单个非显式转换函数到的类类型 存在整数或枚举类型 (12.3)。 [...] 内的任何声明 switch 语句可以用一个或多个 case 标签标记为 如下:

case <em>constant-expression</em> :

constant-expression 应该是一个转换后的常量表达式 (5.19) 的转换条件的提升类型。没有两个 同一个 switch 中的 case 常量在之后应该具有相同的值 转换为切换条件的提升类型。

【讨论】:

    【解决方案2】:

    你不能那样做。 switch 语句要求所有 case 值都是显式的常量表达式——直观地说,表达式的值可以通过查看它们来确定。

    这实际上是一个特性:当我看到switch 时,我立即知道控制流不会依赖于运行时值。如果值在运行时发生变化,则使用不同的习语,继续条件

    if(value == expected) {
        return true;
    } else if(value == -1) {
        printf("Error: Timeout on %s\r\n", id);
        return false;
    } else {
        printf("Error: %s=%02x\r\n", id, value);
        return false;
    }
    

    【讨论】:

      【解决方案3】:

      这只是 C 的要求。value 必须保持不变。只需将 case 更改为 if-elseif-else 语句即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-06
        • 2011-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-02
        • 2021-09-06
        相关资源
        最近更新 更多