转换案例表达比较中使用了哪些提升的类型? [英] What promoted types are used for switch-case expression comparison?

查看:61
本文介绍了转换案例表达比较中使用了哪些提升的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下程序在使用不同的编译器进行编译时将显示未知".为什么会这样?

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, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned 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是否可以包含负值,这由实现定义.可以将字符明确声明为signedunsigned.

It is implementation-defined whether a char can hold negative values. Characters can be explicitly declared signed or unsigned.

...

在任何特定的实现中,简单的char对象都可以采用与signed charunsigned 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.

注意:本文中所有标准语录均来自最终的 C ++ 11 Standard(草稿)

Note: All standard quotations in this post are from the final C++11 Standard (draft) n3337.

这篇关于转换案例表达比较中使用了哪些提升的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆