Wer*_*nze 4 c c++ language-lawyer
使用不同的编译器编译时,以下程序打印"unknown".为什么会这样?
#include "stdio.h"
const char OPTION = (char)(unsigned char)253;
int main(int argc, char* argv[])
{
unsigned char c = 253;
switch (c)
{
case OPTION:
printf("option\n");
break;
default:
printf("unknown\n");
break;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在查看C++标准(N3690 2013-05-05)时,我看到了一个switch子句:
6.4.2 switch语句
2条件应为整数类型,枚举类型或类类型.如果是类类型,则将条件在上下文中隐式转换(第4节)为整数或枚举类型.执行整体促销.switch语句中的任何语句都可以用一个或多个case标签标记,如下所示:
Run Code Online (Sandbox Code Playgroud)case constant-expression :其中constant-expression应该是切换条件的提升类型的转换常量表达式(5.19).在转换为提升类型的开关条件后,同一开关中的两个外壳常数不应具有相同的值.
引用的转换条款:
4标准转换
2 [注意:具有给定类型的表达式将在多个上下文中隐式转换为其他类型:
[...]
- 在switch语句的表达式中使用时.目的地类型是积分(6.4).
[...] - 结束
说明]
变量c的类型为unsigned char,它是一个整数类型.所以不需要晋升!?
如果推广类型是unsigned char我希望比较c == (unsigned char)OPTION,如果产生真实.如果提升类型,int我会期望比较(int)c == (int)OPTION)明显产生错误.
我的问题是:上述计划中使用的推广类型是什么?C和C++标准中的相关条款是什么?
升级类型将int如以下部分所述:
4.5p1整体促销[conv.prom]整数型的以外的prvalue
bool,char16_t,char32_t,或wchar_t其整数转换秩(4.13)小于的秩int可以被转换成类型的prvalueint如果int可以表示源类型的所有值; 否则,源prvalue可以转换为类型的prvalueunsigned int.
它的实现定义了char是有符号的还是无符号的,可以在标准的以下部分中阅读;
3.9.1p1基本类型[basic.fundamental]它是实现定义的,是否
char可以保持负值.可以显式声明字符signed或unsigned....
在任何特定实现中,普通
char对象可以采用与asigned char或unsigned char;实现定义的值相同的值.
之前引用的部分意味着char在以下行上的强制转换不必产生值253.
const char OPTION = (char)(unsigned char)253;
Run Code Online (Sandbox Code Playgroud)
如果char被设置为能够在char为8bit 的平台上保持负值,253则不适合并且很可能OPTION是-3初始化之后的值.
在整体提升之后,在你的帖子中的开关在语义上等同于下面的if-else语句,因为我们有一个条件和一个默认情况.
unsigned char c = 253;
// .---------.-------------------- integral promotion
// v v
if ((int)c == (int)OPTION) {
printf ("OPTION\n");
} else {
printf ("DEFAULT\n");
}
Run Code Online (Sandbox Code Playgroud)
根据底层实现OPTION可能等于253,或-3; 产生你描述的行为.
注意:本文中的所有标准引用均来自最终的C++ 11标准(草案) n3337.
| 归档时间: |
|
| 查看次数: |
1386 次 |
| 最近记录: |