Vi chiedo se non fosse mai successa cosa simile;
non trovo riferimenti su internet.
Situazione:
Software funzionante da qualche tempo, necessito 2 varaibili
in più che mi manda Arduino verso un Lolin Wemos D1 (esp8266).
Compilo e scarico, nessun problema ma non funziona più !
Inizialmente dubitavo della modifica fatta ma poi...
Carico il medesimo software su un NodeMcu ESP8266 V3.
Stesso problema.
Si comincia con un po' di print a video.
vedo che il software va in crash.
Finale:
una istruzione tipo " VAR = VAR ++; " in un banale ciclo di conteggio
dentro un while non funziona più, resta a 1.
Stessa cosa qualche passo dopo in un ciclo For.. classico "...;i ++".
In ambedue i casi usando un esplicito ( che preferisco )
"VAR = VAR + 1;" e poi "...;i = i + 1" il tutto funziona.
Il problema è che NON consideri come funziona il post-incremento ...
The post-increment operator is used when it is required to increment the value of the variable after evaluating the expression. Therefore, in post-increment value is first used in the expression, and then it is incremented.
Quiundi scrivere b = a++; significa PRIMA fare l'assegnazione e POI fare l'incremento che, ovviamnete, NON altera il risultato dell'assegnazione.
Per fare quello che vuoi fare tu devi usare il pre-incremento ...
As the name suggests, the pre-increment operator alters the value of the variable before using it in any expression. Therefore, we can say that the pre-increment operator increases the value of the variable first and then use it in the expression.
Quindi b = ++a; è la forma esatta per ciò che vuoi fare tu ... PRIMA incrementare a e POI fare l'assegnazione.
Ah ... comunque in C/C++ la forma corretta per fare quello che vuoi fare tu è una riga con il solo post-incremento che va ad incrementare quindi la singola variabile quindi:
Si, è cosa che NON andrebbe fatta e che con il post-incremento effettivamente crea casini, ma, proprio per come è gestito il pre-incremento, NON da alcun problema anche se usi una singola variabile ... a = ++a;, per quanto orrenda a vedersi, prima incrementa 'a' e poi esegue l'assegnazione che, proprio perché 'a' è già stato incrementato, comunque funziona.
Concordo comunque sul fatto che sia una schifezza da non fare.
Guglielmo
EDIT: per inciso, ho il compilatore con i "warning" tutti attivi e ...
... comunque compila tranquillamente il caso del post-incremento, senza segnalare alcun "Undefined behavior" (cosa che invece in altri casi fa) ...
Solo per filosofeggiare ho fatto un po' di ricerche e l'espressione i = i++; NON è classificata tra gli undefined behavior , ma tra gli unspecified behavior perché in realtà il risultato è ben definito, ma è funzione di alcuni casi, enumerabili, di come il compilatore tratta l'espressione ...
Mah ... ripeto, mi sembra un po' giocare sulle parole, però così viene definito e, per il caso specifico, si trovano analizzate e descritte tre diverse strade che il compilatore può prendere e che portano a risultati diversi ...
Ribadisco che è filosofeggiare e che comunque, visto che il risultato NON è certo (dato che è funzione del compilatore usato), è cosa da NON fare.
Si, e tra l'altro si sta comunque parlando del nulla, perché se uno scrive "i = i++" non solo non è corretto farlo, ma significa persino che chi ha scritto quell'istruzione non ha capito (non ha studiato?) il pre/post incremento del linguaggio C, che poi è forse tra i primi capitoli di qualsiasi corso di C.
Per cui la tua risposta (post #5) è perfetta, e avrebbe dovuto chiudere il discorso.
Grazie a Tutti quanti,
In effetti non ho mai studiato il C/C++; ma altre cose a livello industria.
Sono uno smanettone che "copia" parte di esempi e li modifica all'occorrenza.
Infatti programmo esclusivamente in "PLC style".
L'esempio identico di Guglielmo:
for ( i = 0; i < N; i++ ) {
...
}
Non funzionava più !
e con la variabile "i" dichiarata "byte" prima del "for" oppure nella stessa funzione.
Eppure esiste nel reference di Arduino, ed è usato su molte cose da me fatte.
Per me è il compilatore sul mio PC con un problemino, oltre a me, ovvio !.
e DEVE venir compilato correttamente, dopo di che, in esecuzione, DEVE ripetere il contenuto del for per 10 volte e ... non mi sembra possibile che non te lo faccia
Copia/incolla ... così non ci sono errori di battitura e verifica.
Ho incrociato con tutti i miei progettini e tutti sono come hai scritto Tu.
La mia svista grave è stata qui, che in realtà non ha mai funzionato :
byte n = 0;
int SerKO = 0;
while(n < 30){ // LOOP ATTESA DATI
n = Serial.available();
SerKO = SerKO ++; // <<<<<<<<<<<<<< ERRORE !!!!! NON FARE COSI' !!
if (SerKO > (TimeElapsed/100)) {
message = "";
message = (MessString_0 + MessString_41); // Dati KO
bot.sendMessage(CHAT_ID, message);
delay(TimeElapsed);
ESP.deepSleep(0); // KO niente sulla Seriale !!
}
}
E pensare che non l'ho MAI e poi MAI usata, ma scritta solo qui !
Mi sono confuso tra il :
SerKO ++;
e il
SerKO = SerKO +1;
Che funzionano.
Per il ciclo FOR, non so perche' si rifiutava...forse battitura o altro.
Anche qui sintassi usata decine e decine di volte...
Di certo il compilatore va benone, lo scrivente decisamente un po' meno.