Recentemente ho scoperto un fastidioso problema in qualche grande programma che sto sviluppando; mi piacerebbe capire come risolverlo nel modo migliore. Ho ridotto il codice al seguente esempio minimo.Costanti integrali C++ + operatore di scelta = problema!
#include <iostream>
using std::cin;
using std::cout;
class MagicNumbers
{
public:
static const int BIG = 100;
static const int SMALL = 10;
};
int main()
{
int choice;
cout << "How much stuff do you want?\n";
cin >> choice;
int stuff = (choice < 20) ? MagicNumbers::SMALL : MagicNumbers::BIG; // PROBLEM!
cout << "You got " << stuff << "\n";
return 0;
}
ottengo errori di collegamento a gcc 4.1.2 quando si compila con -O0 o -O1 ma tutto è ok quando si compila con -O2 o -O3. Si collega bene con MS Visual Studio 2005 indipendentemente dalle opzioni di ottimizzazione.
test.cpp:(.text+0xab): undefined reference to `MagicNumbers::SMALL'
test.cpp:(.text+0xb3): undefined reference to `MagicNumbers::BIG'
Ho guardato il codice complesso intermedio, e sì, il codice non ottimizzato considerate piccole e grandi come variabili int esterne, mentre l'ottimizzato quello utilizzato i numeri reali. Ciascuna delle seguenti modifiche risolve il problema: ad ogni utilizzo enum {SMALL = 10}
Cast costante (uno)::
Uso enumerazione invece di int per le costanti
(int)MagicNumbers::SMALL
o(int)MagicNumbers::BIG
o ancheMagicNumbers::SMALL + 0
utilizzare una macro:
#define SMALL 10
non si utilizza l'operatore di scelta:
if (choice < 20) stuff = MagicNumbers::SMALL; else stuff = MagicNumbers::BIG;
mi piace la prima opzione migliore (tuttavia, non è l'ideale perché abbiamo effettivamente utilizzare uint32_t invece di int per queste costanti, ed enum è sinonimo di int). Ma quello che voglio veramente chiedere è: di chi è il bug?
Sono io il colpevole per non capire come funzionano le costanti integrali statiche?
Devo incolpare gcc e sperare in una correzione (o forse l'ultima versione ha già una correzione, o forse c'è un oscuro argomento da riga di comando per fare in modo che funzioni)?
Nel frattempo, ho solo compilare il mio codice con le ottimizzazioni, ed è un dolore per il debug: -O3
Enum fortemente tipizzati? Freddo! – dreamlax
E 'ancora "C++ 0x" .. BS dice che "x" è esadecimale. :) –
Dobbiamo prendere le scommesse su questo? ;-) –