3
\$\begingroup\$

While I was reading the STM32 HAL drivers for timers I found this macro:

#define __HAL_TIM_DISABLE(__HANDLE__) \
                    do { \
                      if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0U) \
                      { \
                        (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \
                      } \
                    } while(0)

Since the while part is always wrong there should be basically no loop, and the do-while seems redundant to me. But since they distribute it in the HAL like this, I suppose there is some point? Can anyone point out which?

\$\endgroup\$
2
  • 4
    \$\begingroup\$ This should be asked over at the main stack overflow site, but would be closed as a dup of something like this. \$\endgroup\$
    – brhans
    Commented Sep 19, 2018 at 0:10
  • \$\begingroup\$ Thank you very much. I agree :) Should I best delete the question, or what is the most apropriate way to deal with it? \$\endgroup\$ Commented Sep 19, 2018 at 0:22

1 Answer 1

6
\$\begingroup\$

A do { something; } while (0) is a typical pattern in macros, where you want to make sure that all instructions get executed.

Example why this is important:

#define MY_MACRO() do_something1(); do_something2()

This will work:

MY_MACRO();

but this will not work as intended:

if (some_condition) MY_MACRO();

because it will be preprocessed into:

if (some_condition) do_something1(); do_something2();

The second statement will be executed no matter what the condition said.

A do { ... } while(0) is just a convenient way to make a block of code. It will be optimized out by the compiler anyway, so there is actually no looping involved and no runtime overhead.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Thanks again. I like your answer better concerning understandability from the SO one that brhans linked. But one important think they mentioned over there, which your answer is missing is the merit, that do{}while(0) gives you over using braces { ...code... } in your macro, since {} already is a compound statement, and extra semicolon would thus break usage in an if-body, but the do-while with no semicolon attached allows usage in this situation. Thank you all very much, learning something new every day here ;) \$\endgroup\$ Commented Sep 19, 2018 at 7:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.