隐式转换发生条件
- 在混合类型表达式中,操作数被转换成相同的类型
- 用作 if 语句或循环语句的条件时,被转换为bool类型
- 用于switch语句时,转为整数类型
- 用来初始化某个变量(包括函数实参、return语句),转为变量的类型
隐式转换分类
- 标准转换序列 (注:本文只关注这一点)
- 用户定义的转换序列
- 省略符转换序列? (比如函数 printf )
整数与转换级别
- 整数类型:
有符号 | 无符号 | |
标准整数类型 | signed char | unsigned char |
short | unsigned short | |
int | unsigned int | |
long | unsigned long | |
long long | unsigned long long | |
扩展整数类型 | 比如编译器可能提供 __int128 | 比如可能有 __uint128 |
扩展整数类型(Extended integer types)是编译器实现所提供的,标准整数类型以外的整数类型。它们可以比long long要大,也可以介于两个标准的整数类型之间。
- 整数转换级别
(Integer conversion rank 是这么翻译么?)
long long | > | long | > | int | > | short | > | char |
- 除 char 和 signed char 外(如果char有符号的话),任何两个有符号的整数类型都具有不同的级别(Rank)
- 有符号的整数类型的级别高于比它小的有符号的整数类型的级别
- 无符号整数类型的级别等于其对应的有符号整数类型的级别
-
标准整数类型的级别高于同样大小的扩展整数类型的级别。(比如在 long long为64位,且__int64为扩展整数类型情况下,前者高于后者)
- 布尔类型bool的级别低于任何一个标准的整数类型级别
- char16_t、char32_t、wchar_t 的级别等于它们底层类型的级别
- 相同大小的两个有符号的扩展整数类型间的级别高低,由实现定义
标准转换
转换(Conversion) | 类别(Category) | 级别(Rank) |
无需转换 | Identity | Exact Match |
左值到右值转换 | Lvalue Transformation | |
数组到指针转换 | ||
函数到指针转换 | ||
限定符(Qualification)转换) | Qualification Adjustment | |
整数提升 | Promotion | Promotion |
浮点数提升 | ||
整数转换 | Conversion | Conversion |
浮点数转换 | ||
浮点数-整数转换 | ||
指针转换 | ||
指针到成员转换 | ||
布尔转换 |
- 整数提升
所有级别(Rank)比int低的整数类型(不包括 bool、char16_t、char32_t、wchar_t),如果,如果该类型的所有可能值都能包容在int内,它们被提升为int型,否则被提升为unsigned int型。
char16_t、char32_t、wchar_t 被提升为下列第一个能包含其所有可能值的类型:int、unsigned int、long int、unsigned long int、long long int、unsigned long long int
- 浮点数提升
float 被提升为 double
常规算术转换
usual arithmetic conversions
很多二元操作符在执行之前,将两个操作数转换为同一类型,该类型与表达式的值类型相同。
- 如果操作数 是 scoped enumeration type 类型,不执行任何转换操作;如何另一个操作数类型与此不同,表达式属于 ill-formed
- 如果一个操作数是 long double,另一个转换为 long double
- 否则,如果一个操作数 double,另一个转换为 double
- 否则,如果一个操作数 float,另一个转换为 float
- 否则,对两个操作数均执行"整数提升",然后对提升后的操作数,执行
- 如果两个操作数有相同类型,不需要进一步转换
- 否则,如果都是有符号或都是无符号,低级别(Rand)转换为高级别整数
- 否则,如果无符号的整数级别不低于有符号的整数,有符号整数转换为该无符号的类型
- 否则,如果有符号整数可以包括该无符号类型的所有值,则转换成该有符号类型
- 否则,两个操作数均转换为有符号数对应级别的无符号数类型