转换案例表达比较中使用了哪些提升的类型? [英] What promoted types are used for switch-case expression comparison?
问题描述
以下程序在使用不同的编译器进行编译时将显示未知".为什么会这样?
The following program prints "unknown" when compiled with different compilers. Why is that so?
#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;
}
在查看C ++标准(N3690 2013-05-05)时,我看到了switch的子句:
When looking at the C++ standard (N3690 2013-05-05) I see a clause for switch:
6.4.2 switch语句
2条件应为整数类型,枚举 类型或类类型.如果是类类型,则条件取决于上下文 隐式转换(第4节)为整数或枚举类型. 进行整体促销.开关内的任何语句 语句可以用一个或多个案例标签进行标记,如下所示:
6.4.2 The switch statement
2 The condition shall be of integral type, enumeration type, or class type. If of class type, the condition is contextually implicitly converted (Clause 4) to an integral or enumeration type. Integral promotions are performed. Any statement within the switch statement can be labeled with one or more case labels as follows:
case constant-expression :
其中常量表达式应为 提升类型的转换后的常量表达式(5.19) 切换条件.同一开关中没有两个大小写常数 转换为升级后的类型后,其值应相同 切换条件.
where the constant-expression shall be a converted constant expression (5.19) of the promoted type of the switch condition. No two of the case constants in the same switch shall have the same value after conversion to the promoted type of the switch condition.
引用的转换子句:
4次标准转化
2 [注意:在几种情况下,具有给定类型的表达式将隐式转换为其他类型:
[...]
—在switch语句的表达式中使用时.目标类型是整数(6.4).
[...]
—尾注]
4 Standard conversions
2 [ Note: expressions with a given type will be implicitly converted to other types in several contexts:
[...]
— When used in the expression of a switch statement. The destination type is integral (6.4).
[...]
—end note ]
变量c的类型为unsigned char,它是整数类型.因此,不需要晋升!?
Variable c is of type unsigned char, which is an integral type. So no promotion should be necessary!?
如果提升后的类型为unsigned char
,我期望像c == (unsigned char)OPTION
这样的比较会产生true.如果提升的类型是int
,我希望可以得到类似(int)c == (int)OPTION)
的比较,该比较显然会得出false.
If the promoted type were unsigned char
I would expect a comparison like c == (unsigned char)OPTION
which would yield true. If the promoted type were int
I would expect a comparison like (int)c == (int)OPTION)
which clearly yields false.
我的问题是:上面程序中使用的提升类型是什么? C和C ++标准中有哪些相关条款?
My questions are: What is the promoted type used in the above program? What are the relevant clauses in the C and C++ standards?
推荐答案
涉及什么类型?
升级的类型将为int
,如下节所述:
4.5p1
整体促销[conv.prom]
bool,
char16_t,
char32_t,
或wchar_t
以外的整数类型的prvalue的整数转换等级(4.13)小于int
的等级的prvalue可以转换为如果 int
可以表示源类型的所有值;否则,可以将源prvalue转换为unsigned int
类型的prvalue.
A prvalue of an integer type other than
bool,
char16_t,
char32_t,
orwchar_t
whose integer conversion rank (4.13) is less than the rank ofint
can be converted to a prvalue of typeint
ifint
can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of typeunsigned int
.
为什么代码在不同平台上的行为不同?
它的实现定义了 char 是带符号的还是无符号的,可以在本标准的以下部分中阅读;
Why does the code behave differently on different platforms?
It's implementation defined whether char is signed, or unsigned, as can be read in the following section of the Standard;
3.9.1p1
基本类型[basic.fundamental]
char
是否可以包含负值,这由实现定义.可以将字符明确声明为signed
或unsigned
.
It is implementation-defined whether a
char
can hold negative values. Characters can be explicitly declaredsigned
orunsigned
.
...
在任何特定的实现中,简单的char
对象都可以采用与signed char
或unsigned char;
相同的值,后者是实现定义的.
In any particular implementation, a plain char
object can take on either the same values as a signed char
or an unsigned char;
which one is implementation-defined.
这有什么关系?
前面引用的部分表示在下一行强制转换为char
的值不必产生253
的值.
How is that relevant?
The previous quoted section means that the cast to char
on the following line doesn't have to yield the value of 253
.
const char OPTION = (char)(unsigned char)253;
如果使 char 能够在 char 为8位的平台上保留负值,则253
不适合并且很可能是初始化后,OPTION
将为-3
.
If char is made to be able to hold negative values on a platform where a char is 8bit, 253
won't fit and most likely the value of OPTION
will be -3
after initialization.
由于我们有一个条件和一个默认情况,因此在整体晋升后,您的帖子中的开关在语义上等效于以下 if-else-statement .
The switch, after integral promotion, in your post is semantically equivalent to the below if-else-statement, since we have one condition and a default case.
unsigned char c = 253;
// .---------.-------------------- integral promotion
// v v
if ((int)c == (int)OPTION) {
printf ("OPTION\n");
} else {
printf ("DEFAULT\n");
}
取决于基础实现,OPTION
可能等于253
或-3
;产生您所描述的行为.
Depending on the underlying implementation OPTION
might be equal to either 253
, or -3
; yielding the behavior your described.
Note: All standard quotations in this post are from the final C++11 Standard (draft) n3337.
这篇关于转换案例表达比较中使用了哪些提升的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!