Macros are dangerous because their use resembles that of real functions, but they have different semantics. C99 adds inline functions to the C programming language. Inline functions should be used in preference to preferred over macros when they can be used interchangeably. Making a function an inline function suggests that calls to the function be as fast as possible by using, for example, an alternative to the usual function call mechanism, such as inline substitution. (See also PRE31-C. Never invoke an unsafe macro with arguments containing assignment, increment, decrement, volatile access, or function call, PRE01-C. Use parentheses within macros around parameter names, and PRE02-C. Macro replacement lists should be parenthesized.)
Inline substitution is not textual substitution, nor does it create a new function. For example, the expansion of a macro used within the body of the function uses the definition it had at the point the function body appearsappeared, and not where the function is called; and identifiers refer to the declarations in scope where the body occurs.
Arguably, a decision to inline a function is a low-level optimization detail that the compiler should make without programmer input. The use of inline functions should be evaluated based on the basis of (a) how well they are supported by targeted compilers, (b) what (if any) impact they have on the performance characteristics of your system, and (c) portability concerns. Static functions are often as good as inline functions , and are supported in C90 (unlike inline functions).
Noncompliant Code Example
In this noncompliant code example, the macro CUBE()
has undefined behavior when passed an expression that contains side effects.
...
When the macro definition is replaced by an inline function, the side effect is executed only executed once before the function is called.
...
Wiki Markup |
---|
In this noncompliant code example, the programmer has written a macro called {{EXEC_BUMP()}} to call a specified function and increment a global counter \[[Dewhurst 02|AA. C References#Dewhurst 02]\]. When the expansion of a macro is used within the body of a function, as in this example, identifiers refer to the declarations in scope where the body occurs. As a result, when the macro is called in the {{aFunc()}} function, it inadvertently increments a local counter with the same name as the global variable. Note that this example violates [DCL01-C. Do not reuse variable names in subscopes]. |
...
Wiki Markup |
---|
GNU C (and some other compilers) hadsupported inline functions before they were added to C99 and as a result have significantly different semantics. Richard Kettlewell hasprovides a good explanation of differences between the C99 and GNU C rules \[[Kettlewell 03|AA. C References#Kettlewell 03]\]. |
...
In this example, the ADD_M(3,4)
macro invocation yields a constant expression, while the add_f(3,4)
function invocation does not.
PRE00-EX4: Macros allows can be used to implement type-generic functions that cannot be implemented in the C language without the aid of a mechanism such as C++ templates.
An example of the use of function-like functionlike macros to create type-generic functions is shown in MEM02-C. Immediately cast the result of a memory allocation function call into a pointer to the allocated type.
...