Choosing Between Functions and Macros (Windows CE 5.0)
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