switch-case如何在" case"中处理常量的值?

时间:2014-06-19 19:18:39

标签: c++ switch-statement

我们说我们有

typedef unsigned char       BYTE;
#define     CPUTYPE_INVALID  ((BYTE)-1)

switch语句会出现哪种情况?

BYTE m_CPUTYPE;
m_CPUTYPE = 0xff;

switch (m_CPUTYPE) {
    case 255:
        cout << "hit 1";

    case -1:
        cout << "hit 2";

    case CPUTYPE_INVALID:
        cout << "hit 3";
        break;

    default:
        cout << "no hit";
        break;
}

那会是什么结果呢?请详细说明。

4 个答案:

答案 0 :(得分:4)

  

警告

     

您的代码可能格式错误,如果我们正在处理unsigned char由8位组成的平台(最常见的情况),那肯定是。< / p>


标准说什么?

标准中规定,转换后,两个大小写常量的值与开关条件使用的整数类型相同。

  

6.4.2p2 switch声明 [stmt.switch]

     
    

条件应为整数类型,枚举类型或类类型。如果是类类型,则将条件在上下文中隐式转换(第4节)为整数或枚举类型。执行整体促销。 switch语句中的任何语句都可以用一个或多个案例标签标记,如下所示:

case constant-expression :
         

其中teh 常量表达式应为切换条件的提升类型的转换常量表达式(5.19)。在转换为提升类型的开关条件后,同一开关中的两个外壳常数不应具有相同的值。

  

这意味着 if 整数提升产生的整数类型产生m_CPUTYPE类型,将static_cast<int> ((BYTE)-1)static_cast<int> (255)视为相同的值。该片段格式不正确。


那么,我安全吗?

整合提升是将整数类型提升为另一种类型的方法,如果在处理可能属于不同类型的两个整数值时,这对于简单实现和逻辑是必要的。

  

4.5 整体促销 [conv.prom]

     
    

整数转换等级(4.13)小于等级int的bool,char16_t,char32_t或wchar_t以外的整数类型的prvalue可以转换为int类型的prvalue如果int可以表示源类型的所有值;否则,源prvalue可以转换为unsigned int类型的prvalue。

  

标准中指出,unsigned char等级少于int,因此切换条件的类型将为int,进一步手段; static_cast<int> (-1) != static_cast<int> (255)

但是,在大多数平台上, unsigned char 的最大值为255,这意味着(BYTE)-1)将产生 unsigned char 255。这意味着255 == CPUTYPE_INVALID

switch (m_CPUTYPE) {
case 255:               // (A)
  cout<<"hit 1";
case -1:
  cout<<"hit 2";
case CPUTYPE_INVALID:   // (B), same value as (A)
  cout<<"hit 3";
  break;
default:
  cout<<"no hit";
  break;
}

您有两个案例常量,转化后会产生相同的值:您的代码格式错误

答案 1 :(得分:2)

正如其他人指出的那样,代码实际上是不正确的(意味着它根本不会编译)。 Switch语句不能对同一个值进行多次检查(我不记得了)。所以最后上面的代码不会编译所以我的答案是错误

m_CPUTYPE设置为0xFF,与255十进制相同,因此它将采用第一种情况。

那说因为前两种情况你没有中断语句我怀疑代码会打印hit 1hit 2hit 3

如果你在每个case语句中放置一个中断,它应该选择第一个匹配然后退出。

答案 2 :(得分:0)

CPUTYPE_INVALID255完全相同(其中char是8位),所以我怀疑这甚至会编译(switch语句不能具有相同整数值的情况)。但是,你的switch语句将在第一种情况下出现,然后由于缺少break语句而导致其他情况失败。意味着(如果这甚至编译)您的输出将是hit 1hit 2hit 3

This SO question很好地解释了这些值:

  

假设BYTE = char,由于它转换为-1,因此得到-1   (整数)作为char。它只是-1的C风格演员。

     

这是获得&#34; -1&#34;在系统定义的BYTE类型中   签名或未签名(在这种情况下,它是最大可表示的)。在   签名的案件,表明一个虚假的条目,这是一种常见的做法   使用-1值(或者当数量有限时使用极值值   条目)

答案 3 :(得分:0)

switch中的值受到整数提升,这意味着在典型平台上,它会被提升为int类型。这意味着此情况下的切换值为255类型的int

大小写常量被隐式转换为提升类型的切换值,即int。这意味着您的案例标签的值为-1255(BYTE) -1。如果您的平台上的unsigned char是8位类型,则(BYTE) -1也是255,而您的switch语句无效,因为它有两个案例标签价值255。在C ++中为相同的值指定多个case-label是违法的。

在某些异国情调的平台上,整体晋升产生unsigned int,情况不会有太大变化。其中一个案例标签中的值-1将转换为UNIT_MAX,但重复255标签的问题仍然存在。

此代码可以编译的唯一方法是另一个异常平台,unsigned char类型的宽度超过8位。