Le variabili interi firmate non hanno un comportamento avvolgente nella lingua C. L'overflow intero firmato durante i calcoli aritmetici produce comportamento indefinito. Nota BTW che il compilatore GCC che hai menzionato è noto per l'implementazione Semantica di overflow rigorosa In ottimizzazioni, il che significa che sfrutta la libertà fornita da tali situazioni di comportamento non definite: il compilatore GCC presuppone che i valori interi firmati non si avvolgano mai. Ciò significa che GCC in realtà è uno dei compilatori in cui tu non può Affidati al comportamento avvolgente dei tipi interi firmati.
Ad esempio, il compilatore GCC può supporre che per variabile int i
la seguente condizione
if (i > 0 && i + 1 > 0)
è equivalente a un semplice
if (i > 0)
Questo è esattamente cosa Semantica di overflow rigorosa significa.
Tipi di interi non firmati implementano aritmetico modulo. Il modulo è uguale 2^N
dove N
è il numero di bit nella rappresentazione del valore del tipo. Per questo motivo i tipi di interi non firmati sembrano effettivamente avvolgere su Overflow.
Tuttavia, la lingua C non esegue mai calcoli aritmetici in domini più piccoli di quelli di int
/unsigned int
. Tipo unsigned short int
che menzionate nella tua domanda verrà in genere promosso per digitare int
nelle espressioni prima dell'inizio di qualsiasi calcolo (supponendo che l'intervallo di unsigned short
si adatta alla gamma di int
). Il che significa che 1) i calcoli con unsigned short int
sarà preformato nel dominio di int
, con il trabocco che si verifica quando int
traboccanti, 2) L'overflow durante tali calcoli porterà a comportamenti indefiniti, non a un comportamento avvolgente.
Ad esempio, questo codice produce un avvolgimento intorno
unsigned i = USHRT_MAX;
i *= INT_MAX; /* <- unsigned arithmetic, overflows, wraps around */
mentre questo codice
unsigned short i = USHRT_MAX;
i *= INT_MAX; /* <- signed arithmetic, overflows, produces undefined behavior */
porta a comportamenti indefiniti.
Se no int
Overflow accade e il risultato viene convertito in un unsigned short int
Tipo, viene nuovamente ridotto dal modulo 2^N
, che apparirà come se il valore fosse avvolto.