我们说我们有
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;
}
那会是什么结果呢?请详细说明。
答案 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_INVALID
和255
完全相同(其中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
。这意味着您的案例标签的值为-1
,255
和(BYTE) -1
。如果您的平台上的unsigned char
是8位类型,则(BYTE) -1
也是255
,而您的switch
语句无效,因为它有两个案例标签价值255
。在C ++中为相同的值指定多个case-label是违法的。
在某些异国情调的平台上,整体晋升产生unsigned int
,情况不会有太大变化。其中一个案例标签中的值-1
将转换为UNIT_MAX
,但重复255
标签的问题仍然存在。
此代码可以编译的唯一方法是另一个异常平台,unsigned char
类型的宽度超过8位。