Comment puis-je corriger les avertissements comme: "comparaison entre signé et non signé"?
J'ai été conseillé d'utiliser les options suivantes avec GCC, car il permet d'éviter beaucoup d'erreurs courantes. Il tourne sur un tas de mises en garde et -Werror
les transforme en des erreurs.
gcc -pedantic -W -Wall -Wextra -Wshadow -Wstrict-overflow=5 -Wwrite-strings -std=c99 -Werror
Suivants du code de test:
#include <stdio.h>
int main(void)
{
int arr[8]={0,10,20,30,40,50,60,70};
int x;
printf("sizeof(arr): %d\n", sizeof(arr));
printf("sizeof(int): %d\n", sizeof(int));
for(x = 0; x < sizeof(arr)/sizeof(int); x++)
{
printf("%d\n",arr[x]);
}
return 0;
}
J'obtiens ceci:
test.c:11: error: comparison between signed and unsigned
Je sais que dans un sens, je peux résoudre ce problème est de désactiver les mises en garde, mais ils n'ont pas fait de moi l'utilisation de ces paramètres pour les éteindre à la fin.
Une autre façon est de jeter des trucs, mais on m'a dit que le casting est obsolète.
Aussi, j'ai pu faire x dans un unsigned int
:
unsigned x;
Mais ça ne résout pas le problème général quand je dois comparer les valeurs signées avec des valeurs non signées à l'aide de ces options du compilateur. Est-il le moyen le plus propre au lieu de casting?
source d'informationauteur George | 2009-05-13
Vous devez vous connecter pour publier un commentaire.
Cela dépend vraiment du type de données. Il est possible d'éviter cette implicitement par la coulée des valeurs d'un type qui contient un sur-ensemble de toutes les valeurs dans les entiers signés et non signés type. Par exemple, vous pourriez utiliser une version 64 bits signé, valeur à comparer un entier non signé de 32 bits et un signé 32 bits valeur.
Cependant, c'est un cas de coin et vous avez besoin d'effectuer des opérations comme la vérification de la taille de vos types. Votre meilleure solution est d'utiliser le même type pour les deux opérandes.
Si vous devez jeter, ne considérer que vous pourriez être à l'origine d'un débordement et d'envisager, si cela est important pour votre application ou pas.
Remplacer
par
Dans de tels cas, essayez de savoir si le signés nombre peut jamais avoir une valeur qui va provoquer un débordement. Si non, vous pouvez ignorer l'avertissement. Sinon un cast vers le type non signé (si c'est de la même taille ou plus grand que le composant signé) est assez bonne.
Le nœud de la question est que la comparaison des entiers signés et non signés valeurs admet un étrange cas. Considérons, par exemple, ce qui se passe dans le non signés longueur du tableau est plus grand que le maximum qui peut être représenté par un signé int. La signature de compteur de dépassement de capacité (ce qui reste de "moins que" la taille de la matrice), et vous commencez à adressage de la mémoire que tu ne voulais pas...
Le compilateur génère un avertissement assurez-vous que vous êtes en train de penser à leur sujet. À l'aide de
-Werror
fait la promotion de l'avertissement à une erreur et arrête la compilation.Être rigoureux sur le choix de la signedeness de vos types, ou de jeter le trouble à l'écart lorsque vous êtes sûr qu'il ne s'applique pas, ou de se débarrasser de
-Werror
et d'en faire une stratégie pour répondre à tous les avertissements une solution ou une explication...une option serait le drapeau supplémentaire "-Wno-signe-comparer" 🙂
Une solution de contournement serait de désactiver de manière sélective que l'un avertissement dans ce cas particulier.
GCC a pragma diagnostic ignoré "-Wsomething"
Les versions récentes de GCC (je ne suis pas vraiment sûr depuis quand, mais 4.8.x doit être pris en charge) montrent le correspondant -Wsomething option. Ceci est important car la plupart des options d'alerte ne sont pas définies explicitement, mais en bloc avec des options comme le Mur.
Un message d'erreur devrait ressembler à ceci:
[- Werror signe=-comparez] partie Vous indique que Vous pouvez utiliser "Wsign-comparer les" pour "Wsomething" pour supprimer l'avertissement.
Et bien sûr, Vous ne devriez le faire que lorsque c'est approprié (ce n'est pas tout à fait aider à la lisibilité), par exemple quand exactement le comportement que le compilateur signale est voulu (ou, si Vous ne pouvez pas présenter de plus grands changements dans la base de code).
Vous pouvez déclarer x comme un unsigned int, depuis size_t est pas signé
EDIT:
Si vous ne voulez pas de jeter, et ne veulent pas de la déclarer comme non signé, je ne pense pas qu'il y a beaucoup à faire.
Peut-être des opérations bit à bit sont un moyen de le résoudre, en supprimant le bit de signe. Je dois dire, de l'OMI son très discutable.
Nous supprimer cette alerte dans nos Visual Studio compile, car il se passe beaucoup de choses et presque jamais signifie quelque chose de significatif. Bien sûr, pas toutes les normes de codage permettent.
Vous pouvez effectuer les types d'accord (déclaration des variables pour être size_t ou unsigned int au lieu de int, par exemple), ou vous pouvez lancer, ou vous pouvez modifier votre ligne de la compilation. C'est à ce sujet.
Indépendamment de la coulée de la dépréciation dilemme, j'avais toujours penser à séparer la logique de la boucle for.
Bien que cela utilise le moulage qui vous a dit est obsolète, il efface l'emplacement où le casting est en cours. En général, je déconseille les entasser beaucoup de logique dans votre boucle de déclarations. Surtout dans ton cas où vous utilisez un size_t division, qui (parce que c'est la division entière) pourrait avoir la possibilité de tronquer la réponse. La boucle de déclaration doit être propre et ne doit pas générer des erreurs. Votre casting est présente dans un emplacement différent, ce qui signifie que si vous voulez changer la façon dont vous êtes la création de la gamme, vous n'avez pas de boue sur la déclaration encore plus longtemps.