【问题标题】:constant value for case label for switch statement in c and c++ but show different behaviourc 和 c++ 中 switch 语句的 case 标签的常量值,但显示不同的行为
【发布时间】:2020-07-05 13:45:20
【问题描述】:

对于 c 和 c++ 中的相同程序,当我们使用常量整数变量作为 case 标签时,它仅在 c++ 中有效,而在 c 中无效,当我们使用常量整数数组成员作为 case 标签时,它对 c 和 c++ 都无效.这种行为的主要原因是什么?

//for c
#include <stdio.h>
int main()
{
    const int a=90;
    switch(90)
    {
    case a://error : case label does not reduce to an integer constant
        printf("error");
        break;
    }

    const int arr[3]={88,89,90};
    switch(90)
    {
    case arr[2]://error : case label does not reduce to an integer constant
        printf("Error");
        break;
    }
}

//for c++
#include <stdio.h>
int main()
{
    const int a=90;
    switch(90)
    {
    case a:
        printf("No error");
        break;
    }

    const int arr[3]={88,89,90};
    switch(90)
    {
    case arr[2]://error 'arr' cannot appear in a constant-expression
        printf("Error");
        break;
    }
}

【问题讨论】:

  • 这种行为的原因是 C 和 C++ 各自认为是常量表达式。
  • 尽管有一些非常相似的语法,但 C 和 C++ 是两种 非常 不同的语言,具有不同的语义和行为,通常用于看起来非常相似的事物。这是 C 和 C++ 不同的一种情况。

标签: c++ c switch-statement constants


【解决方案1】:

这种行为的主要原因是什么?

主要原因是 2018 年 C 标准在 6.8.4.2 3 中提到 case 标签“每个case 标签的表达式应为整数常量表达式……”并定义了一个整数常量表达式 在 6.6 6 中:

一个整数常量表达式应该是整数类型,并且只能有整数常量、枚举常量、字符常量、sizeof 其结果为整数常量的表达式、_Alignof 表达式和作为强制转换的直接操作数的浮动常量。整数常量表达式中的强制转换运算符只能将算术类型转换为整数类型,除非作为 sizeof_Alignof 运算符的操作数的一部分。

而 2017 C++ 标准在 9.4.2 中提到 case 标签“constant-expression 应该是一个转换后的常量表达式……”并定义了一个转换后的常量表达式 在 8.20 中,有四页文本,涉及 核心常量表达式整数常量表达式等。

总之,C++ 标准更广泛地说明了在翻译时需要对语言实现进行评估的内容。

术语“常量表达式”是用词不当。更恰当的描述是,这些是语言实现在翻译程序时需要能够解析为特定值的表达式。 C++ 标准比 C 标准需要更多的实现。

【讨论】:

    【解决方案2】:

    6.8.4.2 switch 语句 p3:

    each case label shall be an integer constant expression的表达 并且没有两个 case 常量表达式在同一个 switch 语句转换后的值应该相同。

    6.6 常量表达式 p6:

    一个整数常量表达式应该是整数类型并且应该只 操作数是整数常量、枚举常量、 字符常量,结果为整数的表达式 sizeof 常量和作为直接操作数的浮点常量 演员表。

    这样定义的原因是能够静态计算代码中每个条件的偏移量。否则,通过依次检查每个条件,与嵌套的一系列条件相比,它不会加快代码速度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 2019-09-11
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多