Riprendo la discussione avviata da Robyt qua:
viewtopic.php?f=16&t=29866&start=105La 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:
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);
}
}
dove si vede come una stessa operazione da' due risultati diversi.
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:
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;
^
Visto che si sta lavorando con costanti, il compilatore ha gioco facile e si rende conto che c'e' qualcosa che non va.
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:
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
Il resto nel pomeriggio