246 votes

Pourquoi le comportement défini pour le dépassement d'entier non signé, mais le dépassement d'entier signé n'est-il pas?

Unsigned integer overflow est bien défini par le C et C++ normes. Par exemple, le standard C99 (§6.2.5/9) états de l'

Un calcul impliquant non signé opérandes peuvent jamais de débordement, car un résultat qui ne peut pas être représenté par la résultante de type entier non signé est réduit modulo le nombre qui est plus grand que la plus grande valeur qui peut être représenté par le type résultant.

Cependant, les deux normes de l'état qui a signé débordement d'entier est un comportement indéfini. Encore une fois, à partir du standard C99 (§3.4.3/1)

Un exemple de comportement indéfini est le comportement de débordement d'entier

Est-il historique ou (encore mieux!) une technique de raison de cet écart?

185voto

Pascal Cuoq Points 39606

La raison historique est que c'est seulement les représentations pour la signature de valeurs qui peuvent différer en fonction de la mise en œuvre: un complément, en complément à deux, signe de grandeur. Pour un type non signé il n'y a aucune raison pour que la norme, afin de permettre la variation car il n'est qu'une évidence, en représentation binaire (la norme permet uniquement de représentation binaire).

Pertinentes de devis:

C99 6.2.6.1:3: Valeurs stockées dans les bits non signé par les champs et les objets de type unsigned char doit être représenté à l'aide d'un pur notation binaire.

6.2.6.2:2:

Si le bit de signe est l'un, la valeur doit être modifiée dans l'une des façons suivantes:

- la valeur correspondante avec le bit de signe est 0 annulé (signe et l'ampleur);

- le bit de signe est la valeur −(2N ) (complément à deux);

- le bit de signe est la valeur −(2N − 1) ("complément).


De nos jours, tous les processeurs utiliser en complément à deux de la représentation, mais signé de dépassement de capacité arithmétique est pas encore défini et le compilateur décideurs veulent qu'il reste indéfini, car ils utilisent cette undefinedness pour aider à l'optimisation. Voir par exemple ce billet de blog par Ian Lance Taylor ou cette plainte par Agner le Brouillard, et les réponses à son rapport de bug.

19voto

Mats Petersson Points 70074

Côté de Pascal est de la bonne réponse (qui je suis sûr, est la principale motivation), il est également possible que certains processeurs cause l'exception d'un entier signé de débordement, ce qui bien sûr serait de causer des problèmes si le compilateur a dû "prendre des dispositions pour un autre comportement" (par exemple l'utilisation des instructions supplémentaires pour vérifier la possibilité de débordement et de calculer différemment dans ce cas).

Il est également intéressant de noter que "comportement indéfini" ne signifie pas "ne pas travailler". Cela signifie que la mise en œuvre est autorisé à faire ce qu'il aime dans cette situation. Cette includees faire "la bonne chose" ainsi que "appeler la police" ou de "plantage". La plupart des compilateurs, lorsque cela est possible, choisir "faire la bonne chose", en supposant que c'est relativement facile à définir (dans ce cas, il est). Toutefois, si vous rencontrez des débordements dans les calculs, il est important de comprendre ce qui en fait des résultats, et que le compilateur PEUT faire autre chose que ce que vous attendez (et que cela en fonction sur la version de compilateur, de l'optimisation des paramètres, etc).

7voto

supercat Points 25534

En plus des autres questions susmentionnées, ayant unsigned mathématiques envelopper rend l'entier non signé types se comportent comme abstrait groupes algébriques (ce qui signifie que, entre autres choses, pour toute paire de valeurs X et Y, il existe une autre valeur Z tels que X+Z seront, si elles sont correctement exprimés, à l'égal Y et Y-Z seront, si elles sont correctement exprimés, à l'égal X). Si des valeurs non signées ont été simplement de stockage-les types d'emplacement et de ne pas intermédiaire types d'expression (par exemple, si il n'y avait pas non signé équivalent de la plus grande de type entier, et des opérations arithmétiques sur les types non signés sont comportés comme s'ils étaient d'abord converti à plus de types signés, alors il n'y aurait pas autant besoin d'défini le comportement d'habillage, mais il est difficile de faire des calculs dans un type qui n'a pas par exemple un additif inverse.

0voto

Jim Points 2789

Le bit de débordement est défini lorsque le bit le plus élevé provient d'une somme. Ceci est facilement marqué avec des nombres non signés, car le nombre le plus élevé est 0b11111111 (8 bits). Mais pour les numéros signés, le matériel n'est pas en place car le numéro non signé (8 bits) le plus élevé est 0b01111111. Le bit de transfert de matériel ne fonctionne pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X