Search code examples
cnested-loops

top level `continue` in nested loop C instead of current level loop


How do I make continue goes to the top level of loop? I mean like this:

for(;;){ // top level loop
   statement1;
   for(;;){ // second level loop
      statement2;
      if (condition1){
         continue; // I expect it continue to the start of top level so it will execute statement1.
      }
   }
   statement3;
}

This is my real case why I got problem above, basically my program is sending data with UDP socket which the data should be sent fast. I know UDP is unrealiable but it's okay the data is tolerated with loss too.

 for (;;) {  // Streaming data...
    camera_fb_t* fb = esp_camera_fb_get();
    size_t quotient = fb ->len / UDP_BUF_SIZE;
    size_t remainder = fb ->len % UDP_BUF_SIZE;
    unsigned int i = 0;
    for (; i < quotient; i++) {  // sending packet by packet.
      if (uwc_udp_send_raw((const void*)(fb ->buf + (i * UDP_BUF_SIZE)),
                           UDP_BUF_SIZE) < 0) {
        ESP_LOGE(uwc_tag_event, "Error in iteration: %i", i);
        uwc_udp_send_raw("ERR",3); // Tell receiver there was corrupt during send data.
        esp_camera_fb_return(fb);
        continue; // I expect it continue to the top level
      }
    }
    if (remainder) {  // last packet to be sent if remainder exist
      uwc_udp_send_raw((const void*)(fb ->buf + (i * UDP_BUF_SIZE)),
                       remainder);
      ESP_LOGE(uwc_tag_event, "Error in last iteration!");
    }
    esp_camera_fb_return(fb);
  }

Solution

  • You don't need a flag or continue or goto:

    for (;;) {
        camera_fb_t *uwcCamFb = esp_camera_fb_get();
        unsigned char *from = uwcCamFb->buf;
        size_t toSend = uwcCamFb->len;
    
        for( int i = 0; toSend > 0; i++ ) {
            size_t sendSize = toSend > UDP_BUF_SIZE ? UDP_BUF_SIZE : toSend;
            if( uwc_udp_send_raw( from, sendSize ) < 0) {
                ESP_LOGE( uwc_tag_event, "Error in iteration: %i", i );
                uwc_udp_send_raw( "ERR", 3 );
                break;
            }
            toSend -= sendSize;
            from += sendSize;
        }
        // Update...
        // Removed conditional as it reflected flawed OP logic...
        // if( toSend == 0 )
            esp_camera_fb_return( uwcCamFb );
    }
    

    If you need/want to distinguish the LAST packet, add if( toSend < UDP_BUF_SIZE ) to log that particular error message instead...

    It seems your OP used both fb and uwcCamFb... I can only guess this corrects that apparently mistake...

    (Thank you to @Persixty for a bug report that has been fixed.)