Page 1 of 1

BLE gatt_client ( do while(0) )

Posted: Fri Feb 15, 2019 3:19 pm
by filipESP
Hi.
I wonder about the do{}while(0) loop but I don't know what is the adventage of using this code in the esp_gattc_cb() function.
Could anybody explain it?

Re: BLE gatt_client ( do while(0) )

Posted: Sat Feb 16, 2019 4:50 am
by ESP_Sprite
Is this part of a macro (#define bla)? If so, this is probably what's happening: https://gcc.gnu.org/onlinedocs/cpp/Swal ... colon.html

Re: BLE gatt_client ( do while(0) )

Posted: Mon Feb 25, 2019 4:53 pm
by filipESP
I mean about this code:

Code: Select all

    do {
        int idx;
        for (idx = 0; idx < PROFILE_NUM; idx++) {
            if (gattc_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
                    gattc_if == gl_profile_tab[idx].gattc_if) {
                if (gl_profile_tab[idx].gattc_cb) {
                    gl_profile_tab[idx].gattc_cb(event, gattc_if, param);
                }
            }
        }
    } while (0);

Re: BLE gatt_client ( do while(0) )

Posted: Tue Feb 26, 2019 3:46 pm
by phatpaul
Maybe so that they could declare a new variable int idx; vs. declaring it at the top of the function.

That would have also been possible without the do{}while(0).
You could have just started a new section with a curly bracket i.e.

Code: Select all

void function() 
{
  blah;
  blah;

  {
    int idx;
    for (idx = 0; idx < PROFILE_NUM; idx++) {
      blah;
    }
  }
}

Re: BLE gatt_client ( do while(0) )

Posted: Wed Feb 27, 2019 10:02 am
by filipESP
OK, and what is the difference between use:

Code: Select all

void function() { blah; blah; { int idx; for (idx = 0; idx < PROFILE_NUM; idx++) { blah; } } }
and:

Code: Select all

void function() { int idx; blah; blah; { for (idx = 0; idx < PROFILE_NUM; idx++) { blah; } } }
?

Re: BLE gatt_client ( do while(0) )

Posted: Wed Feb 27, 2019 2:11 pm
by phatpaul
I think this discussion is getting off-topic from the forum ESP32 IDF, but it's interesting...

In the trivial case that you provided, I don't think there is much if any difference in function, performance, or memory usage.

But in some cases you may want to wait to put variables on the stack until they are needed. This is good practice to keep the stack small.

Code: Select all

void function() 
{
  blah;
  blah;

  {
    char big_buffer1[255] = {0};
    int idx;
    for (idx = 0; idx < PROFILE_NUM; idx++) {
      blah;  // i.e. do something with big_buffer1
    }
  } // big_buffer1 is released from the stack automatically when execution exits this section
  
  {
    char big_buffer2[255] = {0};
    int idx;
    for (idx = 0; idx < PROFILE_NUM; idx++) {
      blah;  // i.e. do something with big_buffer2
    }
  } // big_buffer2 is released from the stack automatically when execution exits this section
}
Notice that there is never a time that both big_buffer1 and big_buffer2 are both on the stack.

Note you could have achieved the same by making each section into a function, but for style/readability this explicit inline may be preferred.

Re: BLE gatt_client ( do while(0) )

Posted: Tue Mar 05, 2019 4:16 am
by ESP_Tianhao
Agree with phatpaul.

I tend to keep the variables just in the section which use it. Not only related to stack use, but also make code looks more logical.

But there's another discussion about `{}` and `do {} while {0}`, which is better? :roll: