The problem here is that your first cli() is a
function, whereas your second cli() (the macro) is a
statement.
Remember that macros are expanded by the preprocessor, i.e. before the compiler even gets to see the source.
If you define:
Code:
#define cli() { asm("cli") }
and then write
Code:
int main()
{
foo();
cli();
bar();
}
that will get expanded to
Code:
int main()
{
foo();
{ asm("cli"); };
bar();
}
It should be easy to see where the extra brackets and the additional semicolon could lead to troubles, e.g. in an [tt]if[/tt] statement.
A traditional way of encapsuling multi-line blocks in a macro (taking the first of your later examples) is the do-while-block:
Code:
#define cli() do { asm("cli"); } while (0)
That way, the trailing semicolon gets "eaten" by the while-statement.
A macro cannot "return" a value, as it is not a function. With a bit of skill, you can make a macro
evaluate to a certain value, which for all practical purposes is the same. Beware of side-effects, syntactical loopholes and multiple evaluation of parameters, though.
Bottom line, stay away from macros unless you really
must use them.