J'utilise des fichiers non signés partout et je ne suis pas sûr de devoir le faire. Cela peut être des colonnes id primaire de la base de données aux compteurs, etc. Si un nombre ne doit jamais être négatif, j'utiliserai toujours un unsigned int.
Cependant, je remarque dans le code de quelqu'un d'autre que personne ne semble le faire. Y a-t-il quelque chose de crucial que je néglige?
Edit: Depuis cette question, j'ai également remarqué qu'en C, renvoyer des valeurs négatives pour les erreurs était chose courante plutôt que de lancer des exceptions comme en C ++.
c++
c
programming-practices
wting
la source
la source
for(unsigned int n = 10; n >= 0; n --)
(boucles infiniment)Réponses:
Lorsque les calculs impliquent des types signés et non signés, ainsi que des tailles différentes, les règles de promotion du type peuvent être complexes et conduire à un comportement inattendu .
Je crois que c’est la principale raison pour laquelle Java a omis les types unsigned int.
la source
int
ne poseraient pas cette difficulté, cependant (puisque tous les calculs favoriserontint
); Je n'ai rien de bon à dire sur l'absence d'un type d'octets non signés.Je pense que Michael a un argument valable, mais pour l’OMI, tout le monde utilise int tout le temps (surtout
for (int i = 0; i < max, i++
), c’est parce que nous l’avons appris ainsi. Lorsque chaque exemple d'un livre " apprendre à programmer " est utiliséint
enfor
boucle, très peu de gens vont jamais remettre en question cette pratique.L'autre raison est qu'il
int
est 25% plus court queuint
, et nous sommes tous paresseux ... ;-)la source
++
lors de l’incrémentation, malgré le fait que son comportement particulier est rarement nécessaire et peut même conduire à un retournement inutile des copies si l’index de la boucle est un itérateur ou un autre type non fondamental (ou si le compilateur est vraiment dense) .Encoder les informations de plage en types est une bonne chose. Il applique des nombres raisonnables au moment de la compilation.
De nombreuses architectures semblent avoir des instructions spécialisées pour traiter les
int
->float
conversions. La conversion deunsigned
peut être plus lente (un tout petit peu) .la source
Le mélange de types signés et non signés peut vous plonger dans un monde de douleur. Et vous ne pouvez pas utiliser tous les types non signés, car vous rencontrerez des objets ayant une plage valide comprenant des nombres négatifs ou ayant besoin d'une valeur pour indiquer une erreur, et -1 est le plus naturel. Le résultat net est donc que beaucoup de programmeurs utilisent tous les types d'entiers signés.
la source
Pour moi, les types sont beaucoup sur la communication. En utilisant explicitement un unsigned int, vous me dites que les valeurs signées ne sont pas des valeurs valides. Cela me permet d’ajouter des informations lors de la lecture de votre code en plus du nom de la variable. Idéalement, un type non anonyme m'en dirait plus, mais cela me donne plus d'informations que si vous aviez utilisé ints partout.
Malheureusement, tout le monde n’est pas très conscient de ce que son code communique, et c’est probablement la raison pour laquelle vous voyez des données partout, même si les valeurs ne sont au moins pas signées.
la source
J'utilise
unsigned int
en C ++ pour les index de tableaux, principalement, et pour tout compteur qui commence à 0. Je pense qu'il est bon de dire explicitement "cette variable ne peut pas être négative".la source
Vous devez vous en préoccuper lorsque vous avez affaire à un entier qui pourrait atteindre ou dépasser les limites d'un entier signé. Étant donné que le maximum positif d'un entier 32 bits est 2 147 483 647, vous devez utiliser un entier non signé si vous savez qu'il ne sera jamais négatif et que b) pourrait atteindre 2 147 483 648. Dans la plupart des cas, y compris les clés de base de données et les compteurs, je ne m'approcherai jamais de ce type de chiffres. Je ne me préoccupe donc pas de me demander si le bit de signe est utilisé pour une valeur numérique ou pour indiquer le signe.
Je dirais: utilisez int sauf si vous savez que vous avez besoin d'un int non signé.
la source
C'est un compromis entre simplicité et fiabilité. Plus le nombre de bogues pouvant être détectés lors de la compilation est élevé, plus le logiciel est fiable. Différentes personnes et organisations sont sur différents points de ce spectre.
Si vous effectuez une programmation très fiable dans Ada, vous utilisez même différents types pour des variables telles que la distance en pieds par rapport à la distance en mètres, et le compilateur la signale si vous les attribuez accidentellement à l'autre. C'est parfait pour la programmation d'un missile guidé, mais excessif (jeu de mots) si vous validez un formulaire Web. Il n'y a pas nécessairement quelque chose qui cloche dans les deux cas, pourvu que cela réponde aux exigences.
la source
Je suis enclin à être d'accord avec le raisonnement de Joel Etherton, mais j'arrive à la conclusion opposée. À mon avis, même si vous savez qu'il est peu probable que les nombres s'approchent des limites d'un type signé, si vous savez que des nombres négatifs ne se produiront pas, il y a très peu de raisons d'utiliser la variante signée d'un type.
Pour la même raison, j’ai, dans quelques instances choisies, utilisé
BIGINT
(entier 64 bits) plutôt queINTEGER
(entier 32 bits) dans des tables SQL Server. La probabilité que les données atteignent la limite de 32 bits dans un délai raisonnable est minime, mais si cela se produisait, les conséquences dans certaines situations pourraient être assez dévastatrices. Assurez-vous de bien mapper les types entre les langues, sinon vous allez vous retrouver avec une étrange curiosité vraiment très loin dans le futur ...Cela dit, certaines choses, telles que les valeurs de clé primaire de base de données, signées ou non signées, importent peu, car à moins de réparer manuellement des données erronées ou quelque chose du genre, vous ne traitez jamais directement avec la valeur; c'est un identifiant, rien de plus. Dans ces cas, la cohérence est probablement plus importante que le choix exact de la signature. Sinon, vous vous retrouvez avec des colonnes de clé étrangère signées et d'autres non signées, sans motif apparent - ou encore cette étrange curiosité.
la source
Je recommanderais qu'en dehors des contextes de stockage et d'échange de données restreints en espace, on utilise généralement des types signés. Dans la plupart des cas où un entier signé 32 bits serait trop petit, mais qu'une valeur non signée 32 bits suffirait pour aujourd'hui, la valeur non signée 32 bits ne sera pas longue non plus.
Les temps principaux à utiliser pour les types non signés sont ceux qui assemblent plusieurs valeurs en valeurs plus grandes (par exemple, conversion de quatre octets en un nombre de 32 bits) ou en décomposant des valeurs plus grandes en valeurs plus petites (par exemple, en stockant un nombre de 32 bits sous forme de quatre octets). ), ou quand on a une quantité qui est supposée "se retourner" périodiquement et qu’il faut la gérer (pensez à un compteur de service public résidentiel; la plupart d’entre eux ont suffisamment de chiffres pour s’assurer qu’ils ne se renverseront pas entre les lectures si elles sont lues trois fois par an, mais pas suffisamment pour ne pas se retourner pendant la durée de vie utile du compteur). Les types non signés ont souvent assez d '"étrangeté" pour être utilisés uniquement dans les cas où leur sémantique est nécessaire.
la source
size_t
est non signé etptrdiff_t
est signé.J'utilise des ints non signés pour clarifier mon code et son intention. Une des choses que je fais pour me protéger contre les conversions implicites inattendues lorsque je fais du calcul avec des types signés et non signés consiste à utiliser un raccourci non signé (2 octets en général) pour mes variables non signées. Ceci est efficace pour plusieurs raisons:
Le principe général est que le type de vos variables non signées doit avoir un rang inférieur à celui des variables signées afin de garantir la promotion du type signé. Vous n'aurez alors aucun comportement de débordement inattendu. Évidemment, vous ne pouvez pas vous en assurer tout le temps, mais (le plus), il est souvent faisable de le faire.
Par exemple, récemment, j'en ai eu quelques uns comme ceci:
Le littéral '2' est de type int. Si i était un unsigned int au lieu d'un unsigned short, alors, dans la sous-expression (i-2), 2 serait promu à un unsigned int (puisque unsigned int a une priorité plus élevée que signé). Si i = 0, la sous-expression est égale à (0u-2u) = une valeur massive due au débordement. Même idée avec i = 1. Cependant, comme i est un court non signé, il est promu au même type que le littéral '2', qui est signé int, et tout fonctionne bien.
Pour plus de sécurité: dans les rares cas où l'architecture que vous implémentez fait int en entier 2 octets, les deux opérandes de l'expression arithmétique peuvent être promus en unsigned int dans le cas où la variable courte unsigned ne correspond pas. dans le 2-byte int signé, ce dernier a une valeur maximale de 32 767 <65 535. (Voir https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsigned pour plus de détails). Pour vous protéger contre cela, vous pouvez simplement ajouter un static_assert à votre programme comme suit:
et il ne compilera pas sur les architectures où int est égal à 2 octets.
la source