Errata corrige (dovuto al fatto che avevo scritto il post in 4 momenti diversi): 16bit-> 2^16-> 65536. Quindi i valori possibili spaziano da 0 a 65535.
Ovviamente A=65534; A=A+2;A varra' 0. Errore mio.
Per quanto riguarda il casting e' da fare un distinguo. Per gli interi il compilatore si fa furbo (anche senza ottimizzazione) e dice "aspetta va', se b e' un byte, perche' devo modificare b in un long se poi il risultato va a finire sempre in un byte? Quindi ignora il casting della variabile b.
Di seguito il codice assembly che permette di capire cosa fa il processore.
Codice:
uint8_t b=255;
b=long(b)+1;
LDS R24,$0100
SUBI R24,$FF
STS 0100,R24
Il primo comando carica nel registro R24 il valore che c'e' in memoria all'indirizzo 0x0100 (255).
Poi, il che e' interessante, sottrae dal registro R24 il valore 0xFF (255). Quindi per aggiungere 1 toglie 255 dal valore iniziale.
Infine salva il risultato presente nel registro R24 nell'area di memoria all'indirizzo 0x0100.
Come vedi, il casting non e' stato preso in considerazione e ha lavorato come se il casting non ci fosse.
Nel caso di un casting float, il codice assembly si complica parecchio (non avendo un coprocessore matematico, il nostro povero uP deve emulare via sw i calcoli in virgola mobile).
In questo caso il compilatore fa il casting della variabile, usa 4 registri (32bit) fa tutti i conti in virgola mobile e, alla fine, salva in memoria solo i byte che servono (nel caso in cui la variabile dove salvi il risultato fosse un byte, salverebbe solo l'ultimo byte, se fosse un int salverebbe gli ultimi due byte, ecc...). Alla fine, per come e' fatto il sistema esadecimale, ti ritrovi sempre un overflow.
Puoi postare il codice dove ti risulta che si blocca al valore massimo?