Simple while() loop resets my bool

why is the while() comand making my bool false on execution ; when i run this I get
flag =1
flag=0

I should never print the second flag statment and it should be true still not 0(false)

#include "Arduino.h"

bool net_flag=true;

void setup() {
Serial.begin(115200);// put your setup code here, to run once:
delay(1000);
Serial.printf("flag = %d \r\n",net_flag);
while(net_flag);
Serial.printf("flag = %d \r\n",net_flag);
}

void loop() {
// put your main code here, to run repeatedly:

}

Welcome to the forum

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

Please post your full sketch, using code tags when you do

Posting your code using code tags prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination

On what board? What platform? What compile options? It's not a standard Uno R3 or anything similar, that's for sure. Serial.printf is a dead giveaway.

In other words - details. Tell us exactly what it is you are doing so that others can try to reproduce it.

1 Like

it is a ESP32 series board no hardware just simple esp32 I dont have any thing running. it is as basic as it can get I would expect the while loop to act like while(1); which only prints the first statment as it should as the while loop never becomes false. bur when I add a variable it falls out of the loop

Which board exactly? There's umpteen different ESP32 based board to choose from.

What platform version? 2.0.14? 2.0.17? 3.something? What?

What compile options?

If you don't tell us exactly, in detail, what you're done, how do you expect anyone to be able to figure out what going on?

my Arduino IDE 2.3.6 I just started using arduino IDE so it is the default that you download .
this while loop issue is on several boards for example Heltec WiFi LoRa 32(v3) . I get the feeling that the compiler is messing with the code thinking that i did this in error. I have done the same code on several othe IDEs and they all worked as expected.

I've asked twice and you still won't answer. Good luck with your project.

Here you go. I know, it’s a lot of work to do… get over it.

#include "Arduino.h"

bool net_flag = true;

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.printf("flag = %d \r\n", net_flag);
  while (net_flag);
  Serial.printf("flag = %d \r\n", net_flag);
}

void loop() {
}

Not sure what you are looking for I am new to Arduino but a while() loop shoiuld run on any board and it should work the same on any board. How do you find the compile options?

#include "Arduino.h"

bool net_flag = true;

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.printf("flag = %d \r\n", net_flag);
  while (net_flag);
  Serial.printf("flag = %d \r\n", net_flag);
}

void loop() {
}

Instead of the dumb delay, try waiting for Serial to wake up before proceeding, and let us know if that helps.

Doesn’t seem related, shouldn’t be, but it’s something I’ve fought before with ESP32, which I rarely use.

How do you expect that loop to ever exits, since it doesn't do anything with net_flag inside the loop (and there are no interrupts/etc.)

(But I don't see how it would ever print flag=0)

I don't understand the compiler optimizations/behavior with your code, but if you declare the control variable as volatile

//bool net_flag = true;
volatile bool net_flag = true;

You will get equivalent behavior from

while(1);
while(net_flag);

Where the execution will stop with the semicolon and the next next line will not be printed.

Yes that worked adding the volatile made the differance . I am not sure why the original didn't work. thank you so much

I tested your code on an ESP32-C3 and on a C6 and it does exactly as you described.
There must be a bug in the compiled code.
By just adding something in the "while" it stops where it should.
Weird!

#include "Arduino.h"

bool net_flag=true;
int a = 2;

void setup() {
  Serial.begin(115200);// put your setup code here, to run once:
  delay(1000);
  Serial.printf("flag = %d \r\n",net_flag);
  while(net_flag) {
    a = 21;
  };
  Serial.printf("flag = %d \r\n",net_flag);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Using Wokwi is an easy way to get the assembly output. Without volatile

  Serial.printf("flag = %d \r\n", net_flag);
400d15b6:	fa9b81        	l32r	a8, 400d0024 <_stext+0x4> (3ffbdb60 <net_flag>)
400d15b9:	fa9bb1        	l32r	a11, 400d0028 <_stext+0x8> (3f400120 <_flash_rodata_start>)
400d15bc:	0008c2        	l8ui	a12, a8, 0
400d15bf:	07ad      	mov.n	a10, a7
400d15c1:	0057a5        	call8	400d1b3c <_ZN5Print6printfEPKcz>
  while (net_flag);
  Serial.printf("flag = %d \r\n", net_flag);
400d15c4:	fa99b1        	l32r	a11, 400d0028 <_stext+0x8> (3f400120 <_flash_rodata_start>)
400d15c7:	0c0c      	movi.n	a12, 0
400d15c9:	07ad      	mov.n	a10, a7
400d15cb:	005725        	call8	400d1b3c <_ZN5Print6printfEPKcz>

I don't know ESP32 assembly, but I'd guess the compiler is out-smarting you and immediately setting the bool to false (in a12, with no loop) so that it can print what you asked for. It cannot be otherwise. In contrast, with volatile

400d15c6:	0058e5        	call8	400d1b54 <_ZN5Print6printfEPKcz>
  while (net_flag);
400d15c9:	0020c0        	memw
400d15cc:	000682        	l8ui	a8, a6, 0
400d15cf:	748080        	extui	a8, a8, 0, 8
400d15d2:	ff3856        	bnez	a8, 400d15c9 <_Z5setupv+0x45>
  Serial.printf("flag = %d \r\n", net_flag);
400d15d5:	0020c0        	memw
400d15d8:	0006c2        	l8ui	a12, a6, 0
400d15db:	fa93b1        	l32r	a11, 400d0028 <_stext+0x8> (3f400120 <_flash_rodata_start>)
400d15de:	74c0c0        	extui	a12, a12, 0, 8
400d15e1:	07ad      	mov.n	a10, a7
400d15e3:	005725        	call8	400d1b54 <_ZN5Print6printfEPKcz>

the loop code is generated (bnez -> "branch"-something), because as volatile, some other thread might change the variable in a way that can be seen. Unlike before, the code is potentially valid.

I am thinking it is in the optimizations in the compiler I tried what you did and I still did not get it to behave as you would expect but making the bool argument a volatile did work. This makes it so the compiler will not optimize it. I think?

How do you turn off optimizations in the Arduino IDE

By hacking the platform.txt file (and maybe the boards.txt file, not 100% sure) of the platform.

My advice: don't !!

please read the complete thread. The while(net_flag); is deliberate, and the concern is, the printing of flag=0 should not happen, but does.

The number of seriously capable contributors on this forum who fail to read for context before posting is getting rather depressing.

The problem appears to be related to optimization and undefined behavior as explained by @PieterP in Posts 21 - 23 of This Thread.

4 Likes