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?

War es hilfreich?

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 chars 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top