How to break an infinite for(;;) loop in C?

18,225

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?

Share:
18,225
NLed
Author by

NLed

Updated on July 01, 2022

Comments

  • NLed
    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
    NLed about 12 years
    Can 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
    LihO about 12 years
    @Fendi : I have updated my answer. Should be perfectly clear now.
  • NLed
    NLed about 12 years
    Thank 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
    LihO about 12 years
    @Fendi : function myMagicLoop could return some value, then you would replace return; by return 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
    NLed about 12 years
    Thank you very much I got it ! One more thing, if I do not use value = myMagicLoop(); , what will the return commands be used for in I should stop if statements ?
  • LihO
    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 you return value; but still call it simple as myMagicLoop();. Also you can define some special value indicating problem (for example -1 if you plan to return int) but I would rather use exceptions in that case.
  • NLed
    NLed about 12 years
    Thats helpful thank you :) I like how the case function was used here
  • NLed
    NLed about 12 years
    Is this similar to using a semaphore ?
  • visual_learner
    visual_learner about 12 years
    Not to suggest something heretical, but if you don't want to put this all in a function, you could replace return; with goto END; and put END: after the outer loop. I think using goto to perform nested-loop breaking is perfectly acceptable. goto is really only dangerous when you start jumping backwards.
  • LihO
    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
    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 of goto helps you sleep at night... ;)
  • NLed
    NLed about 12 years
    I can't say that I didn't think of using goto, it seems reasonable. But this method works perfectly so I'm happy ! :D