2011-12-20 12 views
7

Od czasu włączenia standardu C++ 0x w g ++, zacząłem widzieć błędy "zwężania konwersji", szczególnie podczas konwersji z "int" na " krótki "chociaż rozumiem, że błąd dotyczy znacznie szerszego pokosu conversions.Jakie są konsekwencje ignorowania zwężenia konwersji w C++ 0x

Czy ktoś może rzucić nieco światła na racjonalne wprowadzenie tego dodatkowego poziomu bezpieczeństwa ?, Jakie są możliwe konsekwencje wyłączenia tego błędu? (oprócz potencjalnej utraty precyzji).

Dzięki.

+35

[Twoja rakieta może eksplodować] (http://www.ima.umn.edu/~arnold/disasters/ariane.html) –

+0

Jeśli kiedykolwiek pracuję na rakiecie, z pewnością będę o tym pamiętać ;) –

+3

To jest coś, co stworzyło _warunki_ zawsze, na zawsze, na zawsze i na dzień, i to jest dobre. Teraz to jest _error_, jest dyskusyjne, czy to dobrze, ponieważ łamie kompilację istniejącego, prawdopodobnie poprawnego kodu. Jednak uniemożliwia to niemożność śledzenia błędów, więc widzę racjonalne uzasadnienie. Nie wyłączałbym takiej logiki błędu, ponieważ kiedy przypadkowo wyrzucisz górną połowę wartości i mają one znaczenie, twój kod nadal działa dobrze, dopóki tego nie zrobi, a wtedy nie wiesz dlaczego. – Damon

Odpowiedz

11

od operatorów przypisania przydział i złożonych [expr.ass]

znaczenie X = {v}, gdzie T jest typu skalarne ekspresji x, jest to, że X = T (v) z tym wyjątkiem, że niedozwolona jest konwersja zawężająca (8.5.4).

iz List-inicjalizacji [dcl.ini.list]

Jeśli konwersja zwężenie (patrz poniżej) jest potrzebny do konwersji dowolnego z argumentów, program jest złego powstały.

Zasadniczo nie można tego zignorować, program jest źle sformułowany w obliczu zawężających się konwersji.

Od zgodność Realizacja:

Wdrożenia są wymagane do zdiagnozowania programy użyć takiego rozszerzenia, które są źle sformułowane według niniejszej normy międzynarodowej. Po wykonaniu tych czynności mogą jednak kompilować i uruchamiać takie programy.

Bjarne Stroustroup powiedzieć this:

Zapobieganie zwężenie

problem: C i C++ niejawnie obcina:

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

jednak W C++ 0x, {} inicjalizacji nie wąski:

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 

Sposób C++ 0x unika wiele niezgodności jest opierając się na rzeczywistych wartościach inicjalizatorów (takich jak 7 w powyższym przykładzie), kiedy może (a nie tylko wpisać) podejmując decyzję o zwężającej się konwersji. Jeśli wartość można przedstawić dokładnie tak, jak typ docelowy, konwersja nie zwęża się.

char c1{7};  // OK: 7 is an int, but it fits in a char 
char c2{77777}; // error: narrowing 

Zauważ, że zmiennoprzecinkową do liczby całkowitej konwersji są zawsze uważane zwężenie - nawet 7,0 do 7.

to w sposób, zwężenie zwiększa również bezpieczeństwo typu.

+0

Doskonała, szczegółowa odpowiedź. Dziękuję bardzo. –

Powiązane problemy