忽略C ++ 0x中缩小转换的后果是什么?

时间:2011-12-20 16:39:26

标签: c++ g++ c++11 narrowing

自从用g ++打开C ++ 0x标准后,我开始看到'缩小转换'错误,特别是在从'int'转换为'short'时,尽管我理解错误涵盖了更广泛的范围conversions

任何人都可以了解引入这种额外安全级别的理由吗?禁用此错误会产生什么后果? (除了潜在的精确度损失)。

感谢。

1 个答案:

答案 0 :(得分:12)

来自分配和复合赋值运算符 [expr.ass]

  

在   x = {v}的含义,其中T是表达式x的标量类型,是x = T(v)的标量类型,但不是   允许缩小转换率(8.5.4)。

列表初始化 [dcl.ini.list]

  

如果需要缩小转换(见下文)来转换任何参数,程序就会格式不正确。

所以基本上你不能忽视它,你的程序在转换变窄的情况下是不正确的。

来自实施合规性

  

诊断程序需要实现   根据本国际标准使用不正确的扩展。但是,这样做之后,他们就可以编译和执行这些程序。

Bjarne Stroustroup说this

  

防止缩小

     

问题:C和C ++隐式截断:

   int x = 7.3;        // Ouch!
    void f(int);
    f(7.3);         // Ouch!
  

但是,在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.

因此,在某种程度上,缩小也会增加类型安全性。