integer overflow différence entre entiers signés et non signés

Le
Taurre
Bonjour à tous,

Dans le cas d'un dépassement d'entier, la norme C opère une différenc=
e entre les entiers signés et non signés. En effet, dans le premier cas=
, le comportement est indéterminé alors que dans le second il y aura =
« wrap around » (C11 [n1570] § 6.2.5 al 9 p 40). J'aurais voulu conna=
ître l'origine d'une telle distinction ?

Aussi, comment celle-ci se matérialise-t-elle sur certaines architectures=
? Je veux dire, sur un processeur x86 ou x86_64, il y a un « wrap around=
» dans les deux cas et il n'y a aucune vérification de la part du proc=
esseur (il y a un juste un drapeau qui est levé s'il y a dépassement de=
la capacité d'un registre me semble-t-il). Je me demande donc comment un=
e architecture ferait pour distinguer une arithmétique signée d'une ari=
thmétique non signé afin d'avoir un comportement différent suivant le=
cas (je ne sais pas si je suis clair) ?

Merci d'avance pour vos réponses.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #24610591
Taurre
Dans le cas d'un dépassement d'entier, la norme C opère une différence
entre les entiers signés et non signés. En effet, dans le premier cas, le
comportement est indéterminé alors que dans le second il y aura « wrap
around » (C11 [n1570] § 6.2.5 al 9 p 40). J'aurais voulu connaître
l'origine d'une telle distinction ?



S'il y a peut-être eu des machines ne proposant pas d'opérations sur les
entiers non-signés, celles qui en ont n'ont pas de variations sur leur
effet. Tandis qu'il y a des variations sur le comportement des opérations
sur les signés et la norme C cherche à permettre l'implémentation la plus
naturelle pour l'architecture plutôt qu'à favoriser la portabilité.

Aussi, comment celle-ci se matérialise-t-elle sur certaines architectures ?
Je veux dire, sur un processeur x86 ou x86_64, il y a un « wrap around »
dans les deux cas et il n'y a aucune vérification de la part du processeur
(il y a un juste un drapeau qui est levé s'il y a dépassement de la
capacité d'un registre me semble-t-il). Je me demande donc comment une
architecture ferait pour distinguer une arithmétique signée d'une
arithmétique non signé afin d'avoir un comportement différent suivant le
cas (je ne sais pas si je suis clair) ?



Si dans le cas d'une représentation des entiers en complément à 2, on peut
avoir une seule instruction d'addition capable de traiter à la fois des
entiers signés et non signés (à part les flags, et ce n'est pas toujours le
cas, MIPS -- processeur pourtant conçu avec une approche minimaliste s'il
en est -- a une instruction ADD qui a une interruption en cas d'overflow et
une instruction ADDU), dans le cas des autres représentations prévues par
la norme (complément aux uns et grandeur et signe), ce n'est pas possible,
il faut nécessairement deux instructions (ou en grandeur et signe, avoir
une instruction d'addition qui ne change pas le signe en cas d'overflow
mais fait un wrap around sur la valeur absolue et ne pas utiliser le bit de
signe comme bit de valeur pour les non signés). Dans ces représentation, le
comportement en cas d'overflow a plus de chance d'être une interruption et
il est fortement improbable d'il soit un wrap around aussi simple que celui
du complément à 2.

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Taurre
Le #24615581
Voilà qui répond parfaitement à ma question, merci beaucoup :)
Antoine Leca
Le #24629141
Taurre écrivit :
Dans le cas d'un dépassement d'entier, la norme C opère une différence
entre les entiers signés et non signés. [...]
Aussi, comment celle-ci se matérialise-t-elle sur certaines architectures ?
Je veux dire, sur un processeur x86 ou x86_64, il y a un « wrap around »
dans les deux cas



Pas forcément. Par exemple, avec les jeux d'instructions SSE etc. to
peux implémenter les opérations en utilisant les opérations vectorisées;
et dans ce cadre-là, tu pourrais utiliser l’addition bornée (si le
résultat mathématique dépasse xINT_MAX, le registre reste figé à
xINT_MAX au lieu de contenir une valeur négative).

La seule chose que dis la norme dans ce cas-là, c'est qu'on ne peut pas
présupposer le comportement ; autrement dit que le programme ne *doit*
pas compter sur le fait que l'implémentation utilise un débordement ou
une arithmétique bornée, parfois d'une expression à l'autre ou même
d'une occurrence de boucle à la suivante (ce qui est parfaitement
plausible si l'implémentation déroule la boucle.)


Antoine
Taurre
Le #24648451
Aah ! Je n'aurais pas pensé à la possibilité d'utiliser les
instructions SSE en lieu et place des instructions basiques. Merci
pour la précision :)
Publicité
Poster une réponse
Anonyme