http://meccanicaedintorni.morpel.it/php ... &start=105
La questione puo' meritare di essere approfondita perche' spesso capita (almeno a me, spero di non essere l'unico) di avere comportamenti strani del programma a causa di overflow di variabili.
Questo il programma di robyt:
Codice: Seleziona tutto
boolean stay = true;
unsigned int A = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
while (stay) {
stay = false;
A = 65534 + 2;
Serial.print("Test Overflow A= A+2 " ); Serial.println(A);
A = 65534 + (float)2;
Serial.print("Test Overflow A= A+(float)2 " ); Serial.println(A);
}
}
Quello che manca nel ragionamento e' che tra il programma scritto in C e il codice macchina c'e' il compilatore che ha un suo modo di ragionare (capire questo, per me autodidatta, e' stata una rivelazione).
Per capire cosa fa realmente il programma scritto (visto che passa per l'interpretazione del compilatore) sarebbe da vedere il codice assembly che pero' e' abbastanza ostico.
Se si attiva gli avvisi del compilatore (dall'ide di arduino, file-impostazioni, attivare la spunta su compilatore e caricamento alla voce "mostra un output dettagliato durante:" e scegliere tutti alla voce "warning del compilatore".
In questo modo si avranno anche gli avvisi dati dal compilatore.
Nel caso specifico, il compilatore ci avvisera' con due warning:
Codice: Seleziona tutto
C:\Users\io\Desktop\000\000\000.ino:11:7: warning: large integer implicitly truncated to unsigned type [-Woverflow]
A = 65534 + 2;
^
C:\Users\io\Desktop\000\000\000.ino:13:7: warning: overflow in implicit constant conversion [-Woverflow]
A = 65534 + (float)2;
^
Nel primo warning avvisa che un long verra' troncato in un int.
Nel secondo caso avvisa che c'e' un overflow nella conversione implicita di una costante.
E' interessante vedere cosa fa il compilatore guardando il codice assembly (in questo caso molto semplice):
Codice: Seleziona tutto
stay = false;
STS 0100,R1
A = 65534 + 2;
STS 0161,R1
STS 0160,R1
A = 65534 + (float)2;
LDI R24,$FF
LDI R25,$FF
STS 0161,R25
STS 0160,R24