2011-12-20 24 views
7

Da quando ho acceso lo standard C++ 0x in g ++, ho iniziato a vedere errori di "restringimento delle conversioni", in particolare durante la conversione da "int" a " Insomma, anche se capisco che l'errore copre una parte molto più ampia di conversions.Quali sono le conseguenze dell'ignorare le conversioni di restringimento in C++ 0x

Qualcuno può far luce sul razionale per introdurre questo ulteriore livello di sicurezza ?, Quali sono le possibili conseguenze della disattivazione di questo errore? (a parte la potenziale perdita di precisione).

Grazie.

+35

[Il tuo razzo potrebbe esplodere] (http://www.ima.umn.edu/~arnold/disasters/ariane.html) –

+0

Se mai dovessi lavorare su un razzo, sarò sicuro di tenerlo a mente ;) –

+3

Questo è qualcosa che ha prodotto _warnings_ sempre, per sempre, e per sempre e un giorno, ed è una buona cosa. Ora è un errore, è discutibile se questa sia una buona cosa dal momento che rompe la compilazione del codice esistente, presumibilmente corretto. Tuttavia, impedisce alcuni errori di tracciamento degli errori, quindi posso vedere la logica. Non disabilitarei una simile logica di errore, perché quando si butta via per errore la metà superiore di un valore e hanno un significato, il codice funziona ancora bene finché non lo fa, e quindi non si sa perché. – Damon

risposta

11

Da operatori di assegnazione assegnazione e composti [expr.ass]

La sensi x = {v}, dove T è il tipo scalare dell'espressione x, è quello di x = T (v) tranne per il fatto che non è consentita la conversione di restringimento (8.5.4) .

e da List-inizializzazione [dcl.ini.list]

Se è necessaria una conversione restringimento (vedi sotto) per convertire qualsiasi degli argomenti, il programma è mal formata.

Quindi in pratica non puoi ignorarlo, il tuo programma è mal formato in presenza di conversioni di restringimento.

Da rispetto Attuazione:

Implementazioni sono necessari per diagnosticare i programmi che utilizzare tali estensioni che sono mal formate in base a questo standard internazionale. Fatto ciò, tuttavia, possono compilare ed eseguire tali programmi.

Bjarne Stroustroup dire this:

Prevenire restringimento

Il problema: C e C++ tronca implicitamente:

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

Tuttavia , In C++ 0x, {} di inizializzazione non ristretto:

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 

Il modo C++ 0x evita un sacco di incompatibilità è basandosi sui valori effettivi di initializers (come 7 nell'esempio sopra) quando può (e non solo digita) quando decide che cos'è una conversione restringente. Se un valore può essere rappresentato esattamente come il tipo di destinazione, la conversione non si restringe.

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

noti che in virgola mobile a intero conversioni sono sempre considerati restringimento - anche 7,0 a 7.

Quindi, in un certo senso, restringimento aumenta anche la sicurezza di tipo.

+0

Ottima risposta dettagliata. Grazie mille. –