How to break an infinite for(;;) loop in C?
Solution 1
If you are looking for "switching between 2 infinite loops" it could be "wrapped" by third loop and this "switching" could be done by simple break
.
But since you want your program to stop some day, this loop could be placed within the function and you could use return;
for ending it:
void myMagicLoop()
{
for(;;)
{
for(;;)
{
if ( I should stop )
return;
if ( I should switch to second loop )
break;
}
for(;;)
{
if ( I should stop )
return;
if ( I should switch back to first loop)
break;
}
}
}
And somewhere you just call:
myMagicLoop();
Hope this helps.
Solution 2
This will switch between loop A and loop B.
for (;;)
{
// Loop A
for (;;)
{
if WANT_TO_SWITCH
{
break;
}
}
// Loop B
for (;;)
{
if WANT_TO_SWITCH
{
break;
}
}
}
Solution 3
Alternatively you could consider rewriting this with an event-driven approach. This will of course depend on what your hardware is capable of, but at the very least you should be able to produce some timer events.
Then the code would go something like this:
static volatile bool sensor_1_ready;
static volatile bool sensor_2_ready;
for(;;)
{
switch(state_machine)
{
case READING_SENSOR_1:
if(sensor_2_ready)
{
state_machine = READING_SENSOR_2;
}
else if(sensor_1_ready)
{
process sensor 1
}
break;
case READING_SENSOR_2:
if(!sensor_2_ready && some_timeout_etc)
{
state_machine = READING_SENSOR_1;
}
else if(sensor_2_ready)
{
process sensor 2
}
break;
}
}
void callback_sensor_1 (void) // some sort of interrupt or callback function
{
sensor_1_ready = true;
}
void callback_sensor_2 (void) // some sort of interrupt or callback function
{
sensor_2_ready = true;
}
(Before commenting on the volatile variables, please note that volatile is there to prevent dangerous compiler optimizations and not to serve as some mutex guard/atomic access/memory barrier etc.)
Solution 4
You use break;
to break a loop and pass control beyond its closing brace. For example
for(;;) {
if( whatever ) {
break;
}
}
//break gets you here
Solution 5
The "break" command should do what you need?
NLed
Updated on July 01, 2022Comments
-
NLed almost 2 years
I have a vital infinite for loop that allows a sensor to keep updating its values. However I would like to break that for loop when another sensor brings in new values. How can I switch from one infinite for loop to another?
Current code:
for(;;){ SON_Start(); // Wait 65ms for max range time delay10ms(7); // Read Range i = SON_Read(SON_ADDRESSES[sonarReading]); // pause delayMs(100); if(i<15) drive(200, RadCW); }
What I would like to add:
If
Sensor2
returns a reading (e.g.Sensor2 > 20
), then I want to break the loop and goto another infinite for loop to begin a new function. -
NLed about 12 yearsCan you please expand the idea behind return for this example ? Can you implement a quick example code ?? I just cant get it to work.
-
LihO about 12 years@Fendi : I have updated my answer. Should be perfectly clear now.
-
NLed about 12 yearsThank you ! The
I should stop
if statement would return a value, this value can be used to terminate the loop or used in other if statements ? -
LihO about 12 years@Fendi : function
myMagicLoop
could return some value, then you would replacereturn;
byreturn value;
and yes, you would be able to use this value in code where you call this function:value = myMagicLoop(); if (value...) ...
. If it's what you ask. -
NLed about 12 yearsThank you very much I got it ! One more thing, if I do not use
value = myMagicLoop();
, what will thereturn
commands be used for inI should stop
if statements ? -
LihO about 12 years
return value;
does not mean that you have to use this return value. If you need this function to return value in some cases, it is ok if youreturn value;
but still call it simple asmyMagicLoop();
. Also you can define some special value indicating problem (for example-1
if you plan to returnint
) but I would rather use exceptions in that case. -
NLed about 12 yearsThats helpful thank you :) I like how the case function was used here
-
NLed about 12 yearsIs this similar to using a semaphore ?
-
visual_learner about 12 yearsNot to suggest something heretical, but if you don't want to put this all in a function, you could replace
return;
withgoto END;
and putEND:
after the outer loop. I think usinggoto
to perform nested-loopbreak
ing is perfectly acceptable.goto
is really only dangerous when you start jumping backwards. -
LihO about 12 years@ChrisLutz: There are many people that consider using
goto
"acceptable" and there are also many people that rather change their code in order to avoid using it. Lets say I belong to the second group. -
visual_learner about 12 years@LihO - Fair enough, but I would argue that your "function" isn't really a function, just a block of code that's being unnecessarily isolated from the area where it's used. Unless you needed to run this loop multiple times, in which case yes, it is a function. But ultimately it's a religious argument. You're still conceptually jumping, but if using
return
instead ofgoto
helps you sleep at night... ;) -
NLed about 12 yearsI can't say that I didn't think of using
goto
, it seems reasonable. But this method works perfectly so I'm happy ! :D