do { } while(0) vs. if (1) { } in macros [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
When one needs to execute multiple statements within preprocessor macro, it's usually written like
#define X(a) do { f1(a); f2(a); } while(0)
so when this macro is used inside expressions like:
if (...)
X(a);
it would not be messed up.
The question is: wherever I've seen such expression, it's always do { ... } while(0);. Is there any reason to prefer such notion over (in my opinion more clear one) if (1) { ... }? Or am I wrong in my observations and they are equally popular?

Nope, you're not wrong.
There's actually a nice reason:
#define my_code if (1) { ... }
if (1)
my_code;
The problem is with the ; ! It shouldn't be there... and that would just look strange and not in the spirit of the language. You can either choose to have a code that expands in to two ; in a row, or a code that looks un-c-ish :)
On the other hand, the do-while construction does not have that problem.
Also, as others mentioned, there's an else problem:
if (1)
my_code;
else { ... }
Ignoring the ; issuse, the else block now belongs to the wrong if.

if can be as safe as do/while only if there is else branch. E.g.:
#define X(a) if(1) { f1(a); f2(a); } else{}
Is as safe as:
#define X(a) do { f1(a); f2(a); } while(0)
So that the user can't do:
X(...) else ...;
One difference is that when using do/while it requires a ; at the end, whereas if/else doesn't.

Consider this:
if(foo)
X(a);
else
whatever();
This would expand to:
if(foo)
if(1) { ... }
else
whatever();
Which is bad because now the else belongs to the wrong if.

Using do... while allows you to break out if necessary.

When you use #define X(a) do { ... } while(0) form, it forces you to put ; at the end of the statement X(1).

Related

How do I write if conditions like these in a macro?

I'm quite new to macros.
I know how to use if condition using ternary operator.
How do I convert this into a #define
if(i==j)
{
count=count+1;
break;
}
I try my luck with this but seems like it is wrong:
#define ifcount(i,j) ((i)==(j)? count=count+1\
break:0)
This is the code i'm trying to convert
http://pastebin.com/i7Tuyh00
Using (abusing) macros to change the flow of the program is usually a bad idea, because the people that will read your code (yourself in a few years) may get surprised by unexpected jumps in the program flow.
That said, your problem has nothing to do with the ternary operator. Actually the ternary operator cannot contain a break in its right side, only expressions.
But macros are allmighty, so you can just do:
#define ifcount(i,j) if ((i)==(j)) { count=count+1; break; }
The main problem with this macro is that people will write a ; when using it, and it will break badly if it is used between another if /else pair, without braces:
if (...)
ifcount(a,b);
else // <--- syntax error because the previous ; breaks the if /else relation
...;
The standard solution is to use the do/while(0) idiom:
#define do { ifcount(i,j) if ((i)==(j)) { count=count+1; break; } } while (0)
But that will not work because the break will break this inner while, not the one you want (credit to #abelenky) below.
The only other C statement that allows a compound statement and ends with a ; is this one:
#define ifcount(i,j) if ((i)==(j)) { count=count+1; break; } else
The problem is that if you forget to add the ; when using ifcount(i,j), instead of a compiler error you will get a silently compiling and surprisingly change in behavior.
I don't see any need to use the ternary (?:) operator.
So here is your macro using an if-statement.
#define IfCount(i,j) if ((i)==(j)) { count++; break; }
Usage:
IfCount(x,5);
Okay, what do you guys think of this?
#define IfCount(i,j) if ((i)==(j)) { count++; break; } do{}while(0)
The final, isolated do-while-0 serves a couple of purposes:
Its a place to hang a semi-colon, so the macro usage looks like "normal" C and ends with a semi-colon.
It prevents an inadvertent else-statement afterwards, because the syntax do{}while(0) else is invalid.
Is there anything else it should take care of?

Purpose of #define foo() do { } while (0)

While browsing sources of LinCAN driver, I found some macros that baffled me.
#else /*CONFIG_PREEMPT*/
#define can_preempt_disable() do { } while (0)
#define can_preempt_enable() do { } while (0)
#endif /*CONFIG_PREEMPT*/
I understand the usefulness of
do {
...;
if(condition) break;
...
} while (0);
using break as a kind of throw. I semi-understand wrapping a sequence of functions like
#define FOO() do { foo(); bar(); } while (0)
to avoid caveats with braceless if. I understand sometimes "no-op statements" are required for a #define. But why this particular kind? specifically, empty braces, false condition, do...while? Some syntax caveats I can't quite grasp?
It is a common syntax for notifying the compiler that macro should be treated as a statement instead of as an expression (statements vs expressions).
In this case compiler will alert you if you try to use can_preempt_disable() as an expression. This means that we forced compile-time check that can_preempt_disable() is used as a statement. Compile-time checks are very often desirable.
The complete passage from the relevant file is:
#if !defined(CONFIG_PREEMPT_RT) && ( defined(CONFIG_PREEMPT) ||
(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) )
#define can_preempt_disable preempt_disable
#define can_preempt_enable preempt_enable
#else /*CONFIG_PREEMPT*/
#define can_preempt_disable() do { } while (0)
#define can_preempt_enable() do { } while (0)
#endif /*CONFIG_PREEMPT*/
Thus, the first part is the code you get when you've asked for pre-emption protection, otherwise you get the empty, do-nothing, loops.
I guess they're written like that for the usual reasons, i.e. to ensure that the macro still is a valid statement.
There shouldn't be a terminating semicolon in the definition, since that will be in the code using these, such as this function which begins:
int c_can_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
{
can_preempt_disable();
...
So, clearly the macro is used like any other function call, and the semicolon is right there where the macro is invoked. This is very normal.
UPDATE 2: Defining it to a ; leads to double semicolons which is ugly, at least in my opinion. An empty brace pair {} would work I guess, but this do/while construct is even more idiomatic since it's often used in cases like these.
UPDATE 3: As pointed out in a comment, an empty brace pair won't work since then you can't put a semicolon after the call. Aah. Thanks!

Embedded C programming style [duplicate]

This question already has answers here:
Why use apparently meaningless do-while and if-else statements in macros?
(9 answers)
Closed 9 years ago.
I have noticed a programming style in Embedded C, used for firmware programming:
#define WRITE_REGISTER(reg, value) \
do { \
write_to_register(reg, value); \
} while (0)
How does this do...while (0) help over:
#define WRITE_REGISTER(reg, value) write_to_register(reg, value)
As you can see here the do {} while(0) permits to avoid compilation errors or bad working when there are multiple lines in the macro and you try to call the macro in the same way as a c function (which is the way everyone does).
As an example (I report the one in the link here so you don't need to navigate the page)
#define DO_SOMETHING_HERE(_x) foo(_x); bar(_x);
if( condition )
DO_SOMETHING_HERE(_x);
else
...
will generate a compilation error because it will result in:
if( condition )
foo(_x); bar(_x);;
else
...
Using the do while everything will work fine, infact it will be:
#define DO_SOMETHING_HERE(_x) do{ foo(_x); bar(_x); }while(0)
if( condition )
do{ foo(_x); bar(_x); } while(0);
else
...
Note that in this case putting braces will not save you because:
#define DO_SOMETHING_HERE(_x) { foo(_x); bar(_x); }
if( condition )
{ foo(_x); bar(_x); };
else
...
still generates an error.
In your case I think it's only a coding style because there's one line only.
With this kind of loop definition, you can use break statements within. This allows easier error handling. Example:
do
{
/* A lot of code */
if(error)
break;
/* A lot of code */
{
while(0)

Why use do { } while (0) in macro definition? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
I met code like below:
#define ev_io_init(ev,cb,fd,events) \
do { \
ev_init ((ev), (cb)); \
ev_io_set ((ev),(fd),(events)); \
} while (0)
I want to know why the author use do { } while (0) here.
Is there any difference with this?
#define ev_io_init(ev,cb,fd,events) { \
ev_init ((ev), (cb)); \
ev_io_set ((ev),(fd),(events)); \
}
BTW: the code is from libev, ev_local.h
Consider if( something ) function1(); else function2();
If function1() is actually a macro, just using { } requires you to omit the semicolon at the point of use, but do { } while(0) lets you use exactly the same syntax as for a real function.
(Not using any kind of block construct at all would just generate completely broken code, natch)
Enclosing code with a loop allows for a preprocessor directive to execute multiple statements without "breaking" if-else-constructs. Consider the following:
#define DO_SOMETHING() a();b();c();
void foo()
{
// This is ok...
DO_SOMETHING();
}
void bar()
{
// ...whereas this would trigger an error.
if (condition)
DO_SOMETHING();
else
blah();
}
The second example breaks the if-else-construct because three statements are followed by an else clause. To allow for it to correctly substitute, the instructions in DO_SOMETHING should be enclosed with a do { ... } while(0).
A do{}while(0) allows you to break from the loop:
do{
expr1;
foo();
if ( cond )
break;
expr2;
goo();
} while (0);
It's the same as a simple block {...} except that you can break execution when you want with the break statement. You couldn't do that in a simple code block, unless you have multiple checks, which can get cumbersome. It still gets executed once, because of the condition while(0).

do { ... } while (0) — what is it good for? [duplicate]

This question already has answers here:
Why use apparently meaningless do-while and if-else statements in macros?
(9 answers)
Closed 2 years ago.
I've been seeing that expression for over 10 years now. I've been trying to think what it's good for. Since I see it mostly in #defines, I assume it's good for inner scope variable declaration and for using breaks (instead of gotos.)
Is it good for anything else? Do you use it?
It's the only construct in C that you can use to #define a multistatement operation, put a semicolon after, and still use within an if statement. An example might help:
#define FOO(x) foo(x); bar(x)
if (condition)
FOO(x);
else // syntax error here
...;
Even using braces doesn't help:
#define FOO(x) { foo(x); bar(x); }
Using this in an if statement would require that you omit the semicolon, which is counterintuitive:
if (condition)
FOO(x)
else
...
If you define FOO like this:
#define FOO(x) do { foo(x); bar(x); } while (0)
then the following is syntactically correct:
if (condition)
FOO(x);
else
....
It is a way to simplify error checking and avoid deep nested if's. For example:
do {
// do something
if (error) {
break;
}
// do something else
if (error) {
break;
}
// etc..
} while (0);
It helps to group multiple statements into a single one so that a function-like macro can actually be used as a function. Suppose you have:
#define FOO(n) foo(n);bar(n)
and you do:
void foobar(int n) {
if (n)
FOO(n);
}
then this expands to:
void foobar(int n) {
if (n)
foo(n);bar(n);
}
Notice that the second call bar(n) is not part of the if statement anymore.
Wrap both into do { } while(0), and you can also use the macro in an if statement.
It is interesting to note the following situation where the do {} while (0) loop won't work for you:
If you want a function-like macro that returns a value, then you will need a statement expression: ({stmt; stmt;}) instead of do {} while(0):
#include <stdio.h>
#define log_to_string1(str, fmt, arg...) \
do { \
sprintf(str, "%s: " fmt, "myprog", ##arg); \
} while (0)
#define log_to_string2(str, fmt, arg...) \
({ \
sprintf(str, "%s: " fmt, "myprog", ##arg); \
})
int main() {
char buf[1000];
int n = 0;
log_to_string1(buf, "%s\n", "No assignment, OK");
n += log_to_string1(buf + n, "%s\n", "NOT OK: gcc: error: expected expression before 'do'");
n += log_to_string2(buf + n, "%s\n", "This fixes it");
n += log_to_string2(buf + n, "%s\n", "Assignment worked!");
printf("%s", buf);
return 0;
}
Generically, do/while is good for any sort of loop construct where one must execute the loop at least once. It is possible to emulate this sort of looping through either a straight while or even a for loop, but often the result is a little less elegant. I'll admit that specific applications of this pattern are fairly rare, but they do exist. One which springs to mind is a menu-based console application:
do {
char c = read_input();
process_input(c);
} while (c != 'Q');

Resources