ESP8266: errore somma "VARIABLE ++"

Il problema è risolto ma pongo una domanda.

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.

Arduimo ide 1.18.12 portable
library ESP8266 :
hardware 3.0.2
xtensa-lx106-elf-gcc
3.0.4-gcc10.3-1757bed

Cosa sarà successo ?

Buon Natale a Tutti !!!

Perché non li hai saputi cercare

https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://stackoverflow.com/questions/6716189/i-i-doesnt-increment-i-why&ved=2ahUKEwiz9u6f6YeDAxWFgf0HHf0-DxwQFnoECBIQAQ&usg=AOvVaw2XOurQol70Q4tHZHUZcj2E

Questo è solo uno dei millemila risultati che escono

esatto...che visibilità ha la variabile?

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.

Guglielmo

1 Like

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:

a = a + 1;

si scrive su una sola riga come:

a++;

che incrementa a di 1 senza alcuna assegnazione.

Classico uso nel ciclo for ...

for ( i = 0; i < N; i++ ) {
   ...
}

Guglielmo

Guarda che lui legge e scrive la stessa variabile
E' "Undefined behavior" dalla notte dei tempi

Prova e vedrai che, come ho indicato, funziona ... prima incrementi e poi assegni.

Guglielmo

Ma hai letto bene quello che ha scritto lui?

Se usi Due variabili ci sto
Ma lui ne usa 1

E almeno dal C99 che è cosa brutta e cattiva

Si vede che prima del C99 chi studiava C lo studiava veramente

Dopo evidentemente hanno aperto i cancelli

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) ... :roll_eyes:

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 ... :roll_eyes:

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.

Guglielmo

Solo per aumentare i post :grin: ...
esiste anche la forma
a += 1;

2 Likes

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. :wink:

1 Like

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". :grin:

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 !.

Ciao ed Auguri a Tutti.
Grazie ancora.

Su Arduino puoi tranquillamente fare:

for ( byte i = 0; i < 10; i++ ) {
   ...
   ...
}

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 :roll_eyes:

Copia/incolla ... così non ci sono errori di battitura e verifica.

Guglielmo

Grazie Guglielmo.

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. :smiling_face_with_tear:

Usa sempre il CODE e indenta correttamente!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.