Каковы последствия игнорирования сужающих преобразований в C ++ 0x - PullRequest
7 голосов
/ 20 декабря 2011

С момента включения стандарта C ++ 0x в g ++ я начал видеть ошибки «сужающего преобразования», особенно при преобразовании из «int» в «short», хотя я понимаю, что ошибка охватывает гораздо более широкий диапазон преобразования .

Может ли кто-нибудь пролить свет на рациональное введение этого дополнительного уровня безопасности? Какие возможные последствия отключения этой ошибки? (кроме возможной потери точности).

Спасибо.

1 Ответ

12 голосов
/ 20 декабря 2011

С Операторы присваивания и составного присваивания [expr.ass]

The значение x = {v}, где T - скалярный тип выражения x, означает x = T (v), за исключением того, что нет допускается сужающее преобразование (8.5.4).

и из Инициализация списка [dcl.ini.list]

Если для преобразования какого-либо из аргументов требуется сужающее преобразование (см. Ниже), программа некорректна.

Так что в принципе вы не можете игнорировать это, ваша программа плохо сформирована в присутствии сужающихся конверсий.

С Соответствие реализации :

Реализации необходимы для диагностики программ, которые использовать такие расширения, которые не соответствуют требованиям настоящего международного стандарта. Сделав это, однако, они могут компилировать и выполнять такие программы.

Bjarne Stroustroup говорят это :

Предотвращение сужения

Проблема: 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.

Таким образом, сужение также повышает безопасность типов.

...