Gli operatori aritmetici binari eseguiranno lo usual arithmetic conversions sui loro operandi per portarli a un tipo comune.
Nel caso di i1
, i3
e i5
il tipo corrente sarà unsigned int e così il risultato sarà anche unsigned int. I numeri senza segno si avvolgeranno con l'aritmetica modulo e quindi sottraendo un valore non firmato leggermente più grande si otterrà un numero vicino a int max senza segno che non può essere rappresentato da un int.
Quindi nel caso di i1
si finisce con una conversione definita dall'implementazione poiché il valore non può essere rappresentato. Nel caso di i3
che divide per 2
riporta il valore unsigned nell'intervallo di int e quindi si ottiene un valore int con segno elevato dopo la conversione.
Le sezioni pertinenti formano lo standard di bozza C++ sono le seguenti. Sezione 5.7
[expr.add]:
Gli operatori additivi + e - gruppo da sinistra a destra. Le normali conversioni aritmetiche vengono eseguite per gli operandi di tipo aritmetico o di enumerazione.
I normali conversioni aritmetiche sono coperti in sezione 5
e dice:
Molti operatori binari che prevedono operandi di operazioni aritmetiche o censimento tipo causano conversioni e producono tipi di risultato in modo simile. Lo scopo è quello di produrre un tipo comune, che è anche il tipo del risultato. Questo modello è chiamato usuali conversioni aritmetiche, che sono definite come segue:
[...]
- Altrimenti, se l'operando che ha senza segno tipo intero ha rango superiore o uguale al rango del tipo di altro operando, l'operando con tipo intero con segno deve essere convertito in il tipo di operando con tipo intero senza segno.
e per la conversione da un valore che non può essere rappresentato da un tipo firmata, sezione 4.7
[conv.integral]:
Se il tipo di destinazione è firmato, il valore è invariato se può essere rappresentato nel tipo di destinazione (e nella larghezza del campo di bit ); in caso contrario, il valore è definito dall'implementazione.
e per interi senza segno obbedisce modulo sezione aritmetica 3.9.1
[basic.fundamental]:
interi senza segno devono rispettare le leggi dell'aritmetica modulo 2n dove n è il numero di bit nel valore rappresentazione di quella particolare dimensione del numero intero.48
fonte
2015-09-09 12:07:30
_Incidentalmente, assegnare quel valore a i1 è un comportamento indefinito_ Ne sei sicuro? Ho insegnato che la conversione da unsigned int a signed int è ben definita per tutti i valori di unsigned int. – rozina
Qui non c'è overflow di interi con segno qui. Ci sono conversioni Vedi [conv.integral] (http://eel.is/c++draft/conv.integral). – Sebivor
@rozina: Huh, non avevo mai visto prima che la conversione funzioni diversamente da questo punto di vista. Risolto – Hurkyl