2013-04-18 14 views
7

W plikach źródłowych, które używam w moim projekcie, nie ma porównania między ssize_t i size_t zmiennych:Obsada ssize_t lub size_t

ssize_t sst; 
size_t st; 

if(sst == st){...} 

Chciałabym pozbyć się ostrzeżenia:

warning: comparison between signed and unsigned integer expressions 

Ale nie jestem pewien, którą zmienną należy odrzucić na drugą?

if((size_t)sst == st){...} 

lub

if(sst == (ssize_t)st){...} 

Co jest bezpieczniejsze, lepsze, czystsze? Dzięki

+0

W jakim języku się posługujesz? –

+0

Dodano tag, C++. – rluks

+0

Spróbuj poprzedzić '(signed int)' przed liczbą całkowitą bez znaku. Powinien teraz być zarówno liczbą całkowitą ze znakiem, jak i nie powinien już podawać błędu. –

Odpowiedz

16

Nie ma jednej słusznej odpowiedzi na to pytanie. Istnieje kilka możliwych odpowiedzi, w zależności od tego, co wiesz o wartościach, które mogą przyjmować te zmienne.

  • Jeśli wiesz, że sst jest nieujemna, a następnie można bezpiecznie rzucać sst do size_t, jak to się nie zmieni wartość (nawiasem mówiąc, to co się stanie, jeśli nie masz obsadę w ogóle).

  • Jeśli sst może być ujemne, ale wiesz, że st nigdy nie będzie większy niż SSIZE_MAX, następnie można bezpiecznie rzucać st do ssize_t, jak tego nie zmieni wartości.

  • Jeśli sst może być ujemna, a st może być większa niż SSIZE_MAX, wówczas ani obsada jest prawidłowa; albo można zmienić wartość, powodując nieprawidłowe porównanie. Zamiast tego wykonaj następujące czynności: if (sst >= 0 && (size_t)sst == st).

Jeśli nie jesteś absolutnie pewienże zastosowanie jednego z dwóch pierwszych sytuacjach wybrać trzecią opcję, ponieważ jest to poprawne we wszystkich przypadkach.

+1

+1 dla prostszego wyrażenia - nie ma powodu aby mieć '(st <= SSIZE_MAX)' zawarłem w mojej odpowiedzi. –

3

Albo zadziała dobrze, o ile obie wartości mieszczą się w dodatnim reprezentowalnym zakresie ssize_t.

Jeżeli którakolwiek wartość nie, może skończyć się w kłopoty - sprawdź przypadki przed badaniem równości:

if ((sst >= 0) && (st <= SSIZE_MAX) && (sst == (ssize_t)st)) 
{ 
    ... 
} 

(jestem pewien, że ludzie C++ zaleci uniknąć C- całkowicie obsadzony stylem - nie mam wątpliwości, że ktoś skomentuje lub odpowie i da ci znać właściwą drogę w C++.)

+1

Gdy wykluczysz 'sst <0', możesz po prostu przekonwertować na' size_t' i porównać. –

+0

@StephenCanon, tak. + 1 na to już odpowiedz. –

+1

'static_cast (st)' to nieco bezpieczniejsza obsada C++. – Yakk