Question

J'ai une fonction petit échantillon:

#define VALUE 0

int test(unsigned char x) {
  if (x>=VALUE)
    return 0;
  else
    return 1;
}

Mon compilateur me prévient que la comparaison (x> = VALUE) est vrai dans tous les cas, ce qui est juste, parce que x est un caractère non signé et la valeur est définie avec la valeur 0. Donc, j'ai changé mon code pour:

if ( ((signed int) x ) >= ((signed int) VALUE ))

Mais l'avertissement est à nouveau. Je l'ai testé avec trois versions de GCC (toutes les versions> 4.0, parfois, vous devez activer -Wextra).

Dans le cas a changé, j'ai ce casting explicite et il devrait être une comparaison int signé. Pourquoi est-il prétendre, que la comparaison est toujours vrai?

Était-ce utile?

La solution

Même avec le casting, la comparaison est toujours vrai dans tous les cas de comportement défini. Le compilateur détermine encore que (signed int)0 a la valeur 0, et détermine encore que (signed int)x) est non négatif si le programme a un comportement défini (coulée de non signé en signé est indéfini si la valeur est hors de portée pour le type signé).

Ainsi, le compilateur continue d'avertissement, car il continue d'éliminer le cas d'autre tout à fait.

Modifier : Pour réduire au silence l'avertissement, écrivez votre code comme

#define VALUE 0

int test(unsigned char x) {
#if VALUE==0
  return 1;
#else
  return x>=VALUE;
#endif
}

Autres conseils

x est un unsigned char, ce qui signifie qu'il est compris entre 0 et 256. Comme un int est plus grand qu'un char, coulée unsigned char à signed int conserve encore la chars valeur d'origine. Étant donné que cette valeur est toujours> = 0, votre if est toujours vrai.

Toutes les valeurs d'un sapin unsigned char peuvent parfaitement dans votre int, donc même avec le casting vous ne serez jamais une valeur négative. Le casting dont vous avez besoin est de signed char - cependant, dans ce cas, vous devez déclarer x comme signed dans la signature de la fonction. Il n'y a pas de point mentir aux clients que vous avez besoin d'une valeur non signée alors qu'en fait, vous avez besoin d'une signature.

Le #define de VALUE à 0 signifie que votre fonction est réduite à ceci:

int test(unsigned char x) {
  if (x>=0)
    return 0;
  else
    return 1;
}

Depuis x est toujours passé en tant unsigned char, il aura toujours une valeur entre 0 et 255 y compris, que vous lancez x ou 0 à un signed int dans l'instruction if. Le compilateur vous avertit donc que x sera toujours supérieure ou égale à 0, et que la clause de else ne peut jamais être atteint.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top