Niedawno odkryłem irytujący problem w dużym programie, który rozwijam; chciałbym zrozumieć, jak to naprawić w najlepszy sposób. Przeciąłem kod do następującego minimalnego przykładu.Stałe całki C++ + operator wyboru = problem!
#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;
}
otrzymuję błędy ogniwem w gcc 4.1.2 przy kompilacji z -O0 lub -O1 ale wszystko jest OK podczas kompilacji z -O2 lub -O3. Dobrze łączy się przy użyciu MS Visual Studio 2005, niezależnie od opcji optymalizacji.
test.cpp:(.text+0xab): undefined reference to `MagicNumbers::SMALL'
test.cpp:(.text+0xb3): undefined reference to `MagicNumbers::BIG'
I spojrzał pośredniego kodu maszynowego, i tak, nieoptymalizowanym kod uważane małe i duże jak zewnętrzne zmienne int, a optymalna stosowanej rzeczywistych liczb. Każdy z następującymi zmianami rozwiązuje problemu:
Używaj enum zamiast int dla stałych:
enum {SMALL = 10}
oddanych stała (jednego) przy każdym użyciu:
(int)MagicNumbers::SMALL
lub(int)MagicNumbers::BIG
lub nawetMagicNumbers::SMALL + 0
użyć makra:
#define SMALL 10
nie użyć operatora wyboru:
if (choice < 20) stuff = MagicNumbers::SMALL; else stuff = MagicNumbers::BIG;
Lubię pierwszą opcję najlepiej (ale to nie jest idealny, ponieważ faktycznie używamy uint32_t zamiast int dla tych stałych i enum jest synonimem int). Ale naprawdę chcę zapytać: czyj to jest błąd?
Czy jestem winnym za niezrozumienie, jak działają statyczne stałe całkowe?
Czy powinienem obwiniać gcc i mam nadzieję na poprawkę (czy może najnowsza wersja ma już poprawkę, czy może jest niejasny argument wiersza poleceń, aby to działało)?
Tymczasem, po prostu skompilować mój kod z optymalizacji, i jest to ból do debugowania: -O3
Mocno napisane wyrazy? Chłodny! – dreamlax
To wciąż "C++ 0x" .. BS mówi, że "x" jest szesnastkowo. :) –
Czy mamy wziąć zakłady na to? ;-) –