开发者

Pros and Cons of Different macro function / inline methods in C

According to the C FAQ, there are basically 3 practical methods for "inlining" code in C:

#define MACRO(arg1, arg2) do { \
    /* declarations */ \
    stmt1;   \
    stmt2;   \
    /* ... */  \
    } while(0)    /* (no trailing ; ) */

or

#define FUNC(arg1, arg2) (expr1, expr2, expr3)

To clarify this one, the arguments are used in the expressions, and the comma operator returns the value of the last expression.

or

using the inline declaration which is supported as an extension to gcc 开发者_StackOverflowand in the c99 standard.

The do { ... } while (0) method is widely used in the Linux kernel, but I haven't encountered the other two methods very often if at all.

I'm referring specifically to multi-statement "functions", not single statement ones like MAX or MIN.

What are the pros and cons of each method, and why would you choose one over the other in various situations?


Talking about that specific use of macros, i.e. macros that act as "functions", I'd mention the following advantages of macros that can't be had in an inline function:

Lazy argument evaluation. For example, a macro like this

#define SELECT(f, a, b) ((f) ? (a) : (b))

would preserve the lazy argument evaluation properties of the ternary operator: only the selected parameter is evaluated, while the other is not. A straightforward inline-function analogue would evaluate both arguments in advance, thus doing the extra unnecessary work.

Access to context. Macros can be used to implement some resemblance of "local functions", i.e. repetitive pieces of code that have access to the local variable and parameters of the enclosing function.

Type independence (and type parameters). Macros allow you to write type-independent "functions" (see above example). And in case you can't get rid of type-dependence, you can pass types as parameters to the macro.

The above properties of the macros, which I presented as their pros, could be misused to lead to major failures (and thus could be presented as cons as well). But that's something that can be said of many language features in C.


One pro of using the inline keyword is that you get a check of the types of the arguments via the function prototype. Using macros you get nothing like that, so macros are liable to create strange errors if you put things of the wrong type in them. (Not nearly as horrible as template errors in C++ though.)

One pro of using macros is that you can do funky things like concatenations and turning the macro argument into a string using #arg. Another plus of using preprocessor macros is you can easily check how they expand using cpp to unwind them. This is how you debug those errors.

Another useful point of macro-defined functions is that you can stick a return statement into them to halt the parent function if you need to. With an inline function you have to return a value and then check the return value.


The only pro I can see in using any of the constructs is for making it faster code.

So, choose the one method that gives fastest code!

If it's all the same, then I find it more legible

  1. a 'standard' function
  2. a inline function
  3. the #define ... do {} while(0) approach
  4. the macro with comma separated expressions
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜