自从在c++中启用c++ 0x标准以来,我开始看到'缩小转换'错误,特别是在从'int'转换为'short'时,尽管我知道错误涵盖了更广泛的转换。
有谁能解释一下引入这种额外安全级别的原因吗?禁用此错误的可能后果是什么?(除了潜在的精度损失)。谢谢。
From 赋值和复合赋值操作符[expr.ass]
x={v}的意义,其中T是表达式x的标量类型,除没有外,都是x=T(v)的意义允许窄化转换(8.5.4)。
和 List-initialization [dcl.ini.list]
如果需要窄化转换(见下文)来转换任何参数,则程序是病态的。
所以基本上你不能忽略它,你的程序在存在窄化转换时是病态的。
From 实现遵从性:
实现需要诊断下列程序根据本国际标准,使用这种病态的扩展。然而,在这样做之后,他们可以编译和执行这些程序。
Bjarne Stroustroup说:
防止狭窄
问题:C和c++隐式截断:
int x = 7.3;//哎呀!空白f (int);f (7.3);//哎呀!之前但是,在c++ 0x中,{}初始化不会缩小:
int x0 {7.3}; // error: narrowing int x1 = {7.3}; // error: narrowing double d = 7; int x2{d}; // error: narrowing (double to int) char x3{7}; // ok: even though 7 is an int, this is not narrowing vector<int> vi = { 1, 2.3, 4, 5.6 }; // error: double to int narrowing
c++ 0x避免许多不兼容的方法是,当它可以(而不仅仅是类型)决定什么是窄化转换时,依赖于初始化式的实际值(如上面示例中的7)。如果一个值可以精确地表示为目标类型,则转换不会缩小。char c1{7}; // OK: 7 is an int, but it fits in a char char c2{77777}; // error: narrowing
所以在某种程度上,窄化也增加了类型安全性。注意,浮点数到整数的转换总是被认为是窄化的——即使是7.0到7。