2009-04-16 15 views
5

Mam następujący kod"porównanie jest zawsze prawdziwe ze względu na ograniczony zakres typu danych" ostrzeżenie w C?

//Point.h 
#define WIDTH 8 
#define HEIGHT 8 

typedef struct Point 
{ 
    char x; 
    char y; 
} Point; 

//Board.c 
#include <stdbool.h> 

// Some other functions that we don't care about... 

bool inBounds(Point * p) 
{ 
    return p->x >= 0 
    && p->x <= WIDTH 
    && p->y >= 0 
    && p->y <= HEIGHT; 
} 

Kiedy skompilować ten (PPU-gcc 4.1.1), otrzymuję następujące ostrzeżenie

warning: comparison is always true due to limited range of data type 

chociaż zakres char jest -127 do 127 a WIDTH ma wartość 8, która mieści się w zakresie znaku. Próbowałem już jawnej obsady WIDTH do char, ale nadal mam błąd.

+0

prostu zmienić struct do int, i zobaczyć, co się stało? –

+0

W twoim przypadku potrzebujesz atoi lub statycznego rzutowania dla x i y, a następnie porównaj z wysokością i szerokością. –

Odpowiedz

14

Czy jesteś pewien, że podpisano char? Spróbuj deklarować pola wyraźnie jako signed char i zobacz, co otrzymasz.

+0

Tak, uważam, że char jest unsigned, więc porównanie z 0 będzie zawsze prawdziwe. – Wedge

+13

To zależy od kompilatora. Jeśli * potrzebujesz * char do podpisania, musisz zadeklarować go jako podpisany. –

+0

Tak, naprawia to. Jednak linie, w których pojawiał się błąd, były liniami, w których robiłem porównanie z liczbami dodatnimi (WIDTH i HEIGHT). Dziwne. –

1

Hummm ... nie jest domyślnie znakiem domyślnym? W tym przypadku zakres byłby 0-255, co oznacza, że ​​porównanie> = 0 będzie zawsze prawdziwe

+1

To zależy od platformy i kompilatora. Na przykład GCC na architekturze x86 używa podpisu char domyślnie, podczas gdy GCC na PowerPC Linux używa domyślnie znaku uns. – ephemient

3

Chyba x >= 0 powoduje ostrzeżenie ponieważ char może być realizowany jako unsigned char.

3

Typ char może być podpisany lub niepodpisany. To zależy od wyboru dostawcy kompilatora. Może być nawet dostępna opcja kompilatora. Najwyraźniej char jest dla ciebie niepodpisany, więc zawsze jest większy lub równy zeru, a więc kompilator ostrzega cię.

Tutaj używasz char, aby reprezentować "typ numeryczny, który zajmuje minimalną pamięć". W takim przypadku zalecam jawne użycie signed char lub unsigned char. (Każdy jest inny niż zwykły char, mimo że char musi być podpisany lub niepodpisany.) Zarezerwować char, jeśli przechowujesz dane postaci. W przypadku danych numerycznych należy użyć jednego z dwóch pozostałych typów.

+1

zostało to potwierdzone przez: http://www.network-theory.co.uk/docs/gccintro/gccintro_71.html – dfa

0

Standardy C i C++ zezwalają na podpisywanie lub podpisywanie znaków char, zależnie od platformy i kompilatora. Większość systemów, w tym x86 GNU/Linux i Microsoft Windows, używa podpisanego char, ale te oparte na procesorach PowerPC i ARM zwykle używają unsigned char. (29) Może to prowadzić do nieoczekiwanych rezultatów podczas przenoszenia programów pomiędzy platformami, które mają różne ustawienia domyślne dla typu char.

0

Spróbuj tego:

typedef struct Point 
{ 
    signed char x; 
    signed char y; 
} Point;