# 'do { statement; } while(0)' against 'statement' when writing C macro? [closed]

Which one of the following is preferrable and why when writing C macro?

Type 1

#define I2C_START()                 I2C_WAIT_IDLE(); SSP1CON2bits.SEN  = 1


Type 2

#define I2C_START()               \
do                            \
{                             \
I2C_WAIT_IDLE();          \
SSP1CON2bits.SEN  = 1;    \
}while(0)


One of my colleagues prefers Type 1 while I prefer Type 2. So when both of us work in a project, both of the types are seen throughout the project.

## closed as off-topic by 200_success, Jamal♦Feb 8 '14 at 18:42

If this question can be reworded to fit the rules in the help center, please edit the question.

## locked by Jamal♦Dec 21 '14 at 21:55

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. See the help center for guidance on writing a good question.

• c-faq.com/cpp/multistmt.html explains it in detail. – Alok Apr 16 '11 at 4:20
• This question appears to be off-topic because it is about best practice regarding a specific language feature. See help center. – 200_success Feb 8 '14 at 17:28

I prefer the second one because it can be used with normal compound stamens without modifications or accidentally being used incorrectly.

if (condition)
I2c_START;


Type 1: FAIL
Type 2: OK

Of course with good coding standards that can be avoided (always use '{' '}' on if). But every now and then people can be lazy (or just careless) and the second version prevents accidents from happening.

The best solution is not to use macros. Use functions and let the compiler work out when to inline.

### Edited:

For billy: (Type 3) no do while

#define I2C_START()   \
{                             \
I2C_WAIT_IDLE();          \
SSP1CON2bits.SEN  = 1;    \
}


Unfortunately this fails if you use the else part of the if statement:
The trailing semi-colon (on type 3) marks the end of the if statement thus else is not syntactically allowed. At least this gives you a compilation error unlike above. But Type 2 still works as expected.

if (condition)
I2C_START();
else
std::cout << "FAIL this test\n";


Type 1: FAIL
Type 2: OK
Type 3: FAIL

• Well, you really don't need the "do" and "while (0)" bits for type 2 to prevent this though. A plain block will do just fine. – Billy ONeal Apr 7 '11 at 4:23
• It's syntax thing. Having only {} block will expand to if (...) { ... }; and spare ; is not good. – blaze Apr 7 '11 at 7:17
• @blaze, really? You're worried about a semicolon that only the compiler will see, and ignore? – AShelly Apr 9 '11 at 1:54
• @AShelly: if (foo) do { bar; } while 0; else { mmm; } = ok. if (foo) {bar} ; else {mmm;} = syntax error on else, because spare ; terminated if-statement. Oops :) – blaze Apr 11 '11 at 10:01
• Ok, good point. – AShelly Apr 11 '11 at 19:09

The Linux Kernel Newbies FAQ has an entry on this, since Linux uses it extensively. It's the syntax-safe way of defining these kinds of macros.

• It would be good if you could actually put the content in your answer. – Lyndon White Jun 22 '13 at 9:30
• It's a long FAQ entry, sorry. – The UNIX Man Jul 2 '13 at 2:19

The second form is the safest without having to think too much about the consequences way.

but for what you are using it for? neither really need to be used. It should be a function. I'm taking it this is PIC code.... the overhead of the function call won't cost you that much.

• yes it is pic. we typically write macros for 2/3 lines of register access. – Donotalo Apr 8 '11 at 11:42

I something similar to type two but without the do while as in:

#define I2C_START()               \
do                            \
{                             \
I2C_WAIT_IDLE();          \
SSP1CON2bits.SEN  = 1;    \
}while(0)


The do while could be difficult to understand for an inexperienced coder. I also always use {} even for onliner if statements.

• any inexperience coder should learn what do{}while(0) does. – Donotalo May 5 '11 at 12:22
• Yes. But by keeping it obvious and simple you avoid problems with people that have not or do not want to learn. – Gerhard May 6 '11 at 5:39