Share via


Choosing Between Functions and Macros (Windows CE 5.0)

Send Feedback

Developing an Application > Microsoft C Run-time Library for Windows CE > C Run-time Libraries

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 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
    
  • Use the #undef directive (to undefine the macro definition):

    #include <ctype.h>
    #undef toupper
    

When choosing between a function and a macro, 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 might 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 might treat arguments incorrectly when the macro evaluates its arguments more than once.

    For instance, the towupper macro is defined as this:

    #define toupper(c) ( (islower(c)) ? _toupper(c) :  (c) )
    

    In the following example, the towupper 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 once for the result.

    This increases a by 2 instead of 1. As a result, the value operated on by islower differs from the value operated on by toupper.

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

See Also

Microsoft C Run-time Library for Windows CE | Type Checking | Run-time Routines by Category

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.