Il tipo size_t
non è firmato. La sottrazione di qualsiasi due valori size_t
è definita-comportamento
Tuttavia, in primo luogo, il risultato è definito dall'implementazione se un valore più grande viene sottratto da uno più piccolo. Il risultato è il valore matematico, ridotto al più piccolo residuo positivo modulo SIZE_T_MAX + 1
. Ad esempio, se il valore più grande di size_t
è 65535 e il risultato della sottrazione di due valori size_t
è -3, il risultato sarà 65536 - 3 = 65533. Su un compilatore o macchina diverso con size_t
diverso, il valore numerico sarà diverso.
In secondo luogo, un valore size_t
potrebbe non rientrare nell'intervallo del tipo int
. In questo caso, otteniamo un secondo risultato definito dall'implementazione derivante dalla conversione forzata. In questa situazione, qualsiasi comportamento può essere applicato; deve solo essere documentato dall'implementazione e la conversione non deve fallire. Ad esempio, il risultato potrebbe essere bloccato nell'intervallo int
, producendo INT_MAX
. Un comportamento comune visto su due complementi di macchine (praticamente tutti) nella conversione di tipi di unsigned più larghi (o uguali a larghezza) in stringhe più strette è il troncamento bit semplice: vengono presi abbastanza bit dal valore unsigned per riempire il valore firmato, incluso il suo segno po.
A causa del modo in cui funziona il complemento a due, se il risultato astratto originale aritmeticamente corretto si adatta a int
, la conversione produrrà quel risultato.
Ad esempio, supponiamo che la sottrazione di una coppia di valori a 64 bit size_t
su una macchina a complemento a due produce il valore aritmetico astratto -3, che diventa il valore positivo 0xFFFFFFFFFFFFFFFD
. Quando questo è forzato in un 32 bit int
, il comportamento comune visto in molti compilatori per le macchine a complemento di due è che i 32 bit inferiori vengono presi come l'immagine del risultante : 0xFFFFFFFD
. E, ovviamente, questo è solo il valore -3 in 32 bit.
Quindi il risultato è che il codice è de facto abbastanza portatile perché praticamente tutte le macchine tradizionali sono complemento a due con regole di conversione in base all'estensione segno e bit di troncamento, compreso tra il sottoscritto e senza segno.
Tranne che l'estensione del segno non si verifica quando un valore viene ampliato durante la conversione da non firmato a firmato. Quindi un problema è la rara situazione in cui int
è più largo di size_t
.Se un risultato a 16 bit size_t
è 65533, a causa della sottrazione di 4 da 1, questo non produrrà un valore -3 quando convertito in un 32 bit int
; produrrà 65533!
Se la sottrazione risulta in un numero negativo, [si avvolge] (https://stackoverflow.com/questions/1269019/what-should-happen-to-the-negation-of-a-size-tie -sizeofstruct-foo) secondo [complimento di due] (https://en.wikipedia.org/wiki/Two%27s_complement) – CoryKramer
Il modo in cui lo hai, no non è sicuro. Ma non a causa della matematica stessa. Stai lanciando un risultato 'size_t' (che probabilmente sarà' unsigned long') a un 'int' (signed), che probabilmente è un tipo di dati più piccolo. –
Il tipo di differenza corrispondente di size_t è ptrdiff_t, non int –