标准第 § 8.5.4/7 解释了什么是缩小转换范围 is:
缩小转换是隐式转换
— 从浮点类型到整数类型,或者
— 从 long double 到 double 或 float,或者从 double 到 float,除非源是常量
表达式与转换后的实际值在可以表示的值范围内
(即使无法准确表示),或
— 从整数类型或无作用域枚举类型到浮点类型,除非源
是一个常量表达式,转换后的实际值将适合目标类型,并且将
转换回原始类型时生成原始值,或者
— 从整数类型或无作用域枚举类型到不能表示所有的整数类型
原始类型的值,除非源是常量表达式以及之后的实际值
转换将适合目标类型,并在转换回原始值时生成原始值
原始类型。
然后它不允许在某些列表初始化上下文中进行此类转换,从而给出
例子:
[ 注意:如上所述,在列表初始化的顶层不允许进行此类转换。 - 结尾
注意] [示例:
int x = 999; // x is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x; // OK, though it might narrow (in this case, it does narrow)
char c2{x}; // error: might narrow
char c3{y}; // error: narrows (assuming char is 8 bits)
char c4{z}; // OK: no narrowing needed
unsigned char uc1 = {5}; // OK: no narrowing needed
unsigned char uc2 = {-1}; // error: narrows
unsigned int ui1 = {-1}; // error: narrows
signed int si1 =
{ (unsigned int)-1 }; // error: narrows
int ii = {2.0}; // error: narrows
float f1 { x }; // error: might narrow
float f2 { 7 }; // OK: 7 can be exactly represented as a float
int f(int);
int a[] =
{ 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level
—结束示例]
示例中所示的所有 7 个错误均由
铿锵 3.2/3.3 与-std=c++11
, e.g.
error: non-constant-expression cannot be narrowed from type 'int' to 'char' in initializer list [-Wc++11-narrowing]
gcc 4.7.2/4.8.1 没有将它们报告为错误,但在每种情况下
给出了类似的警告,例如
warning: narrowing conversion of ‘x’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
(因此海湾合作委员会似乎知道合规性要求,但选择容忍不合规性
默认情况下。)
我不明白的是这个例子是如何实现的:
unsigned int ui1 = {-1}; // error: narrows
有资格作为例子。 (同样地,对称si1
示例。)显然
唯一的词语might合格的例子是第四个
和定义中的最后一项缩小转换范围上面给出;但
如果是这样,那么为什么这个例子没有通过限定条件来逃脱除非源是常量表达式并且之后的实际值
转换将适合目标类型,并在转换回原始值时生成原始值
原始类型?一定-1
存在一个整数常量,如果转换为unsigned
然后回来,
仍然产生int -1
?
我缺少什么?