web-dev-qa-db-fra.com

Le dépassement d'entier signé est-il toujours un comportement non défini en C ++?

Comme nous le savons, le débordement d'entier signé est un comportement non défini . Mais il y a quelque chose d'intéressant dans la documentation C++ 11 cstdint:

type entier signé avec une largeur d'exactement 8, 16, 32 et 64 bits respectivement sans bits de remplissage et en utilisant le complément à 2 pour les valeurs négatives (fourni uniquement si le la mise en œuvre prend directement en charge le type)

Voir lien

Et voici ma question: puisque la norme dit explicitement que pour int8_t, int16_t, int32_t et int64_t les nombres négatifs sont le complément de 2, le débordement de ces types est-il toujours un comportement indéfini?

Edit J'ai vérifié les normes C++ 11 et C11 et voici ce que j'ai trouvé:

C++ 11, §18.4.1:

L'en-tête définit toutes les fonctions, types et macros de la même manière que 7.20 dans la norme C.

C11, §7.20.1.1:

Le nom du typedef intN_t désigne un type entier signé de largeur N, sans bits de remplissage et une représentation du complément à deux. Ainsi, int8_t désigne un tel type entier signé avec une largeur d'exactement 8 bits.

71
Archie

le débordement de ces types est-il toujours un comportement indéfini?

Oui. Conformément au paragraphe 5/4 de la norme C++ 11 (concernant toute expression en général):

Si lors de l'évaluation d'une expression, le résultat n'est pas défini mathématiquement ou n'est pas dans la plage de valeurs représentables pour son type, le comportement n'est pas défini. [...]

Le fait que la représentation du complément à deux soit utilisée pour ces types signés ne signifie pas que le module arithmétique 2 ^ n est utilisé lors de l'évaluation des expressions de ces types.

En ce qui concerne l'arithmétique non signée , en revanche, la norme spécifie explicitement que (paragraphe 3.9.1/4):

Entiers non signés, déclarés unsigned, doivent obéir aux lois du module arithmétique 2 ^ n où n est le nombre de bits dans la représentation de la valeur de cette taille particulière d'entier

Cela signifie que le résultat d'une opération arithmétique non signée est toujours " défini mathématiquement ", et le résultat est toujours dans la plage représentable; par conséquent, 5/4 ne s'applique pas. La note de bas de page 46 explique ceci:

46) Cela implique que non signé l'arithmétique ne déborde pas car un résultat qui ne peut pas être représenté par le type entier non signé résultant est réduit modulo le nombre qui est supérieur à la plus grande valeur qui peut être représentée par le résultat type entier non signé.

68
Andy Prowl

Tout simplement parce qu'un type est défini pour utiliser la représentation du complément 2s, il ne s'ensuit pas que le dépassement arithmétique dans ce type soit défini.

Le comportement indéfini du débordement arithmétique signé est utilisé pour permettre les optimisations; par exemple, le compilateur peut supposer que si a > b puis a + 1 > b également; cela ne tient pas dans l'arithmétique non signée où la deuxième vérification devrait être effectuée en raison de la possibilité que a + 1 pourrait se terminer par 0. De plus, certaines plates-formes peuvent générer un signal d'interruption sur un dépassement arithmétique (voir par exemple http://www.gnu.org/software/libc/manual/html_node/Program-Error-Signals.html ); la norme continue de permettre que cela se produise.

23
ecatmur

Je parierais ainsi.

De la documentation standard (p. 4 et 5):

1.3.24 comportement indéfini

comportement pour lequel la présente Norme internationale n'impose aucune exigence

[Remarque: Un comportement indéfini peut être attendu lorsque la présente Norme internationale omet toute définition explicite de comportement ou lorsqu'un programme utilise une construction ou des données erronées. Le comportement non défini autorisé va de l'ignorance complète de la situation avec des résultats imprévisibles, au comportement pendant la traduction ou l'exécution du programme d'une manière documentée caractéristique de l'environnement (avec ou sans émission d'un message de diagnostic), à la fin d'une traduction ou d'une exécution (avec l'émission d'un message de diagnostic). De nombreuses constructions de programme erronées n'engendrent pas de comportement indéfini; ils doivent être diagnostiqués .-- note de fin]

1
EnzoR