Choosing Between Functions and Macros

FROM MSDN

Most Microsoft run-time library routines are compiled or assembled functions, but some routines are implemented as macros. When a header file declares both a function and a macro version of a routine, the macro definition takes precedence, because it always appears after the function declaration. When you invoke a routine that is implemented as both a function and a macro, you can force the compiler to use the function version in two ways:

  • Enclose the routine name in parentheses.
    #include <ctype.h>
    a = toupper(a);    //use macro version of toupper
    a = (toupper)(a);  //force compiler to use function version of toupper
    
  • “Undefine” the macro definition with the #undef directive:
    #include <ctype.h>
    #undef toupper
    

If you need to choose between a function and a macro implementation of a library routine, consider the following trade-offs:

  • Speed versus size. The main benefit of using macros is faster execution time. During preprocessing, a macro is expanded (replaced by its definition) inline each time it is used. A function definition occurs only once regardless of how many times it is called. Macros may increase code size but do not have the overhead associated with function calls.

  • Function evaluation. A function evaluates to an address; a macro does not. Thus you cannot use a macro name in contexts requiring a pointer. For instance, you can declare a pointer to a function, but not a pointer to a macro.

  • Macro side effects. A macro may treat arguments incorrectly when the macro evaluates its arguments more than once. For instance, thetoupper macro is defined as:
    #define toupper(c) ( (islower(c)) ? _toupper(c) :  (c) )
    

    In the following example, the toupper macro produces a side effect:

    #include <ctype.h>
    
    int a = 'm';
    a = toupper(a++);
    

    The example code increments a when passing it to toupper. The macro evaluates the argument a++ twice, once to check case and again for the result, therefore increasinga by 2 instead of 1. As a result, the value operated on by islower differs from the value operated on bytoupper.

  • Type-checking. When you declare a function, the compiler can check the argument types. Because you cannot declare a macro, the compiler cannot check macro argument types, although it can check the number of arguments you pass to a macro. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值