Wie man Typ warf einen wörtlichen in C
-
20-09-2019 - |
Frage
Ich habe eine kleine Beispielfunktion:
#define VALUE 0
int test(unsigned char x) {
if (x>=VALUE)
return 0;
else
return 1;
}
Mein Compiler warnt mich, dass der Vergleich (x> = WERT) in allen Fällen wahr ist, was richtig ist, weil x ein unsigned Charakter und Wert wird mit dem Wert definiert 0, so dass ich meinen Code geändert:
if ( ((signed int) x ) >= ((signed int) VALUE ))
Aber die Warnung kommt wieder. Getestet habe ich es mit drei GCC-Versionen (alle Versionen> 4.0, manchmal müssen Sie ermöglichen -Wextra).
In dem geändertenen Fall, ich habe diese explizite Umwandlung und es sollte ein signed int Vergleich sein. Warum es wird behauptet, dass der Vergleich immer wahr ist?
Lösung
Auch bei der Besetzung, ist der Vergleich immer noch wahr in allen Fällen von definierten Verhalten. Der Compiler bestimmt nach wie vor, dass (signed int)0
den Wert 0 hat, und bestimmt nach wie vor, dass (signed int)x)
nicht negativ ist, wenn Ihr Programm Verhalten definiert wird (von unsigned Casting zu undefiniert unterzeichnet wird, wenn der Wert des zulässigen Bereichs aus für den signierten Typen).
So ist der Compiler weiterhin Warnung, weil es weiterhin ganz den sonst Fall zu beseitigen.
Bearbeiten : die Warnung zum Schweigen bringen, schreiben Sie Ihren Code wie
#define VALUE 0
int test(unsigned char x) {
#if VALUE==0
return 1;
#else
return x>=VALUE;
#endif
}
Andere Tipps
x
ist ein unsigned char
, dh es zwischen 0 und 256. Da ein int
ist größer als ein char
, Gießen unsigned char
zu signed int
behält noch die char
s ursprünglichen Wert. Da dieser Wert immer> = 0, Ihre if
ist immer wahr.
Alle Werte eines unsigned char
lassen sich perfekt in Ihre int
Tanne, so auch bei der Besetzung werden Sie nie einen negativen Wert erhalten. Die Besetzung Sie ist signed char
müssen - aber in diesem Fall, dass Sie x
als signed
in der Funktion Unterschrift erklären. Es gibt keinen Punkt für die Kunden liegen, dass Sie einen Wert ohne Vorzeichen benötigen, während in der Tat Sie ein signiertes brauchen.
Die #define
von VALUE
zu 0
bedeutet, dass Ihre Funktion dieses reduziert wird:
int test(unsigned char x) {
if (x>=0)
return 0;
else
return 1;
}
Da x
immer als unsigned char
übergeben wird, dann wird es immer einen Wert zwischen 0
und 255
inklusive, und zwar unabhängig davon, ob Sie werfen x
oder 0
zu einem signed int
in der if
Aussage. Der Compiler deshalb warnt Sie, dass x
immer größer sein als oder gleich 0
, und dass die else
Klausel nie erreicht werden kann.