Y a-t-il une différence entre 1U et 1 en C?

while ((1U << i) < nSize) { i++; } 

Une raison particulière d’utiliser 1U au lieu de 1 ?

Sur la plupart des compliers, les deux donneront un résultat avec la même représentation. Cependant, selon la spécification C, le résultat d’une opération de décalage de bit sur un argument signé donne des résultats définis par la mise en oeuvre. Ainsi, en théorie, 1U << i est plus portable que 1 << i . En pratique, tous les compilateurs C que vous rencontrerez traitent les décalages de gauche signés comme les décalages de gauche non signés.

L’autre raison est que si nSize n’est pas signé, sa comparaison avec un 1 << i signé 1 << i générera un avertissement du compilateur. Changer le 1 en 1U supprime le message d’avertissement et vous n'avez pas à vous soucier de ce qui se passe si i 31 ou 63 ans.

L'avertissement du compilateur est probablement la raison pour laquelle 1U apparaît dans le code. Je suggère de comstackr C avec la plupart des avertissements activés et d'éliminer les messages d'avertissement en modifiant votre code.

1U n’est pas signé. Il peut porter des valeurs deux fois plus grandes, mais sans valeurs négatives.

En fonction de l’environnement, lors de l’utilisation de U, je peux avoir un maximum de 31 ou 15, sans provoquer de débordement. Sans utiliser U, je peux avoir un maximum de 30 ou 14.

31, 30 sont pour 32 bit int
15, 14 sont pour 16 bit int

Si nSize est un int , il peut atteindre 2147483647 (2 ^ 31-1) au maximum. Si vous utilisez 1 au lieu de 1U alors 1 << 30 vous donnera 1073741824 et 1 << 31 sera -2147483648, et la boucle while ne se terminera jamais si nSize est supérieur à 1073741824.

Avec 1U << i , 1U << 31 sera évalué à 2147483648 et vous pourrez donc l'utiliser en toute sécurité pour nSize jusqu'à 2147483647. Si nSize est un unsigned int, il est également possible que la boucle ne se termine jamais, comme dans ce cas nSize peut être plus grand que 1U << 31 .

Edit: Je ne suis donc pas d'accord avec les réponses qui vous disent que nSize ne doit pas être signé, mais s'il est signé, il ne devrait pas être négatif ...

1U n’est pas signé.

La raison pour laquelle ils ont utilisé une valeur non signée dans cette expression est (je suppose) parce que nSize est également non signée, et les compilateurs (lorsqu’ils sont appelés avec certains parameters) donnent des avertissements lors de la comparaison de valeurs signées et non signées.

Une autre raison (moins probable, à mon avis, mais nous ne pouvons pas savoir sans connaître la valeur que nSize est supposée assumer) est que les valeurs non signées peuvent être deux fois plus grandes que les valeurs signées; de ~ 2 * 10 ^ 9.