2010-09-30 7 views
7

Dzisiaj zrobiłem 64-bitową kompilację mojego projektu po raz pierwszy. Zasadniczo zostało skompilowane, połączone i uruchomione, z wyjątkiem ostrzeżeń narzekających na niezgodność między nowym 64-bitowym typem size_t a prostym typem int. To najczęściej występuje w sytuacjach takich jak ta w moim kodu:Jak uniknąć problemów z typami size_t i int w 64-bitowych wersjach C++?

void func(std::vector<Something> &vec) 
{ 
    int n = vec.size(); 
    for (int i=0; i < n; i++) 
    { 
     ....vec[i].... 
    } 
} 

Jest to dość łatwe do naprawienia, a ja przeczytałem artykuł mówiąc, należałoby raczej użyć size_t lub ptrdif_t jako indeksów pętli. Ale co mogę zrobić w takiej sytuacji?

void outsideLibraryFunc(int n); 

void func(std::vector<Something> &vec) 
{ 
    int n = vec.size(); 
    outsideLibraryFunc(n); 
} 

nie mogę zmienić deklarację funkcji zewnętrznej biblioteki, która oczekuje argumentu typu int, i muszę go przekazywać liczbę elementów wektorowych. Co mogę zrobić, oprócz wyłączenia ostrzeżeń kompilatora?

+0

+1 na P: Nie wiedziałem, że size_t! = Unsigned int – pm100

+0

@ pm100 It * can * be, i na większości systemów 32-bitowych jest, ale nie musi tak być. W szczególności w 64-bitowych systemach wykorzystujących konwencje LP64 lub LLP64 (najnowocześniejsze systemy 64-bitowe), zwykle jest większy niż "unsigned int". –

+0

ssize_t jest czasem dostępny dla podpisanego rozmiaru_trantu – user318904

Odpowiedz

9

Wykonaj wyraźną obsadę na numer int, np.

void outsideLibraryFunc(int n); 

void func(std::vector<Something> &vec) 
{ 
    outsideLibraryFunc(static_cast<int>(vec.size())); 
} 

To nie eliminuje każdy z potencjalnych problemów z konwersji size_t do int, ale robi poinformować kompilator, że robisz konwersję na celu i nie poinformuje o tym.

+0

+1, większą zaletą jest to, że czytając kod, widzisz rzutowanie, które w innym przypadku byłoby niejawne, a przy wiedzy, której nie może mieć kompilator, możesz sprawdzić, czy ma to sens, czy nie. Tak jak w przykładzie: podczas gdy kompilator nie może zapewnić, że wartość zwrócona przez funkcję typu "size_t" zmieści się w 32-bitowej liczbie całkowitej, można ręcznie sprawdzić, czy ma to sens, czy nie. –

3

Oddać? Poważnie, jeśli nie możesz zmienić biblioteki zewnętrznej, niewiele możesz zrobić. Aby uzyskać dodatkowe bezpieczeństwo, sprawdź, czy nie ma przepełnienia.

+0

+1 za sprawdzenie przepełnienia (choć rzadko masz więcej niż 2 biliony obiektów) –

+0

Jak sprawdzić, czy nie ma przepełnienia? Trochę wspomnę o bicie przepełnienia w EFLAGS, ale jak mam uzyskać do niego dostęp w sposób C? – neuviemeporte

+1

@neuviemeporte: if (vec.size()> INT_MAX) {/ * error * /} else {/ * (int) rzutowanie zadziała * /}. Ale jak powiedział Viktor, czek może być przesadzony ... –