2010-06-21 12 views
8
const int bob = 0; 

if(bob) 
{ 
    int fred = 6/bob; 
} 

si ottiene un errore sulla linea di cui è fatto il divario: "Errore C2124: dividere o mod per zero"MSVC++ errore su una divisione per 0 che non accadrà mai! risolvere?

che è zoppo, perché è altrettanto inevitabile che il 'caso' di controllo fallirà, in quanto è la divisione che si tradurrà in un div per 0. francamente non vedo alcun motivo per il compilatore di valutare qualsiasi cosa nel "se", tranne che per assicurare l'integrità del tutore.

in ogni caso, ovviamente, che ad esempio non è il mio problema, il mio problema nasce quando fare cose complicate modello per cercare di fare il più al momento della compilazione del possibile, in alcuni casi, gli argomenti possono essere 0.

c'è comunque risolvere questo errore? o disabilitarlo? o qualsiasi soluzione alternativa migliore:

attualmente l'unico lavoro intorno a cui riesco a pensare (cosa che ho fatto prima quando ho riscontrato lo stesso problema con l'accesso enum ricorsivo) è utilizzare la specializzazione dei modelli per fare il "se".

Oh sì, sto usando Visual Studio Professional 2005 SP1 con la correzione vista/win7.

+0

Si potrebbe provare ad assegnare a una variabile locale quindi dividendo per quello. – Artelius

+2

Non so se funzionerà, ma che ne dici: int fred = 6/(bob? Bob: 1); –

+0

@Jeremy Friesner: carino! che funziona e risolverà il mio problema, sentitevi liberi di metterlo come risposta! – matt

risposta

4

suppongo il compilatore cerca di ottimizzare il frammento di codice dal bob è definito const, in modo che il valore iniziale di fred può essere determinato al momento della compilazione. Forse puoi impedire questa ottimizzazione dichiarando bob non-const o usando la parola chiave volatile.

+0

hai ragione, il problema è che il compilatore esegue internamente i calcoli matematici e cerca un accoppiamento quando tenta di dividere per zero. sfortunatamente il punto di ciò che sto cercando di fare è far sì che il compilatore faccia la matematica in fase di compilazione :(altrimenti, quello che suggerisci risolve l'errore – matt

+0

No, non un'ottimizzazione. compila il tempo – MSalters

3

Puoi fornire maggiori dettagli su ciò che stai cercando di fare con i modelli? Forse puoi usare un modello specializzato per 0 che non fa niente del buon vecchio esempio fattoriale ed evitare del tutto l'errore.

template <int N> 
struct Blah 
{ 
    enum { value = 6/N }; 
}; 

template <> 
struct Blah<0> 
{ 
    enum { value = 0 }; 
}; 
+0

sì, questo risolverebbe anche il mio problema, ed è ciò che intendevo quando ho detto "usa la specializzazione dei modelli per fare il 'se'" come soluzione alternativa nella domanda – matt

+0

Scusa non l'ho notato :) ma è il modo migliore per evitare questi problemi e permette anche al compilatore di fare più lavoro in fase di compilazione. – Gary

+0

sì, è anche l'unico modo che conosco per correggere altri errori di questo tipo, come le chiamate ricorsive, ad esempio, il seguente CRASH il compilatore perché evalora sempre entrambi i lati del "se", fallito o meno: enum {value = (N> 10)? 1337: Blah :: valore}; – matt

3

Il problema - e il compilatore non ha scelta in questo - è che bob è un'espressione costante integrale, come è 6. Pertanto 6/bob è anche un ICE e deve essere valutati in fase di compilazione .

C'è una soluzione molto semplice: inline int FredFromBob(int bob) { return 6/bob; } - un'espressione di chiamata di funzione non è mai un ICE, anche se la funzione è banale e dichiarata in linea.

+0

Sì, la costante può essere utilizzata come parametro del modello. Il compilatore non può semplicemente saltare l'istanza dei modelli, anche se accadessero in una parte di codice irraggiungibile in fase di runtime. – MSalters

Problemi correlati