I always saw examples and cases where using a macro is better than using function.
Could someone explain me with an example the disadvantage of a macro compared to a function?
I always saw examples and cases where using a macro is better than using function.
Could someone explain me with an example the disadvantage of a macro compared to a function?
I did not notice, in the answers above, one advantage of functions over macros that I think is very important:
Functions can be passed as arguments, macros cannot.
Concrete example: You want to write an alternate version of the standard 'strpbrk' function that will accept, rather than an explicit list of characters to search for within another string, a (pointer to a) function that will return 0 until a character is found that passes some test (user-defined). One reason you might want to do this is so that you can exploit other standard library functions: instead of providing an explicit string full of punctuation, you could pass ctype.h's 'ispunct' instead, etc. If 'ispunct' was implemented only as a macro, this wouldn't work.
There are lots of other examples. For example, if your comparison is accomplished by macro rather than function, you can't pass it to stdlib.h's 'qsort'.
An analogous situation in Python is 'print' in version 2 vs. version 3 (non-passable statement vs. passable function).
Macro features:
Function features:
No type checking of parameters and code is repeated which can lead to code bloat. The macro syntax can also lead to any number of weird edge cases where semi-colons or order of precedence can get in the way. Here's a link that demonstrates some macro evil
Adding to this answer..
Macros are substituted directly into the program by the preprocessor (since they basically are preprocessor directives). So they inevitably use more memory space than a respective function. On the other hand, a function requires more time to be called and to return results, and this overhead can be avoided by using macros.
Also macros have some special tools than can help with program portability on different platforms.
Macros don't need to be assigned a data type for their arguments in contrast with functions.
Overall they are a useful tool in programming. And both macroinstructions and functions can be used depending on the circumstances.
Example 1:
whereas:
Example 2:
Compared to:
When in doubt, use functions (or inline functions).
However answers here mostly explain the problems with macros, instead of having some simple view that macros are evil because silly accidents are possible.
You can be aware of the pitfalls and learn to avoid them. Then use macros only when there is a good reason to.
There are certain exceptional cases where there are advantages to using macros, these include:
va_args
.eg: https://stackoverflow.com/a/24837037/432509.
(
__FILE__
,__LINE__
,__func__
). check for pre/post conditions,assert
on failure, or even static-asserts so the code won't compile on improper use (mostly useful for debug builds).struct
members are present before casting(can be useful for polymorphic types).
Or check an array meets some length condition.
see: https://stackoverflow.com/a/29926435/432509
func(FOO, "FOO");
, you could define a macro that expands the string for youfunc_wrapper(FOO);
(assignments to multiple variables, for a per-pixel operations, is an example you might prefer a macro over a function... though it still depends a lot on the context, since
inline
functions may be an option).Admittedly, some of these rely on compiler extensions which aren't standard C. Meaning you may end up with less portable code, or have to
ifdef
them in, so they're only taken advantage of when the compiler supports.Avoiding multiple argument instantiation
Noting this since its one of the most common causes of errors in macros (passing in
x++
for example, where a macro may increment multiple times).its possible to write macros that avoid side-effects with multiple instantiation of arguments.
C11 Generic
If you like to have
square
macro that works with various types and have C11 support, you could do this...Statement expressions
This is a compiler extension supported by GCC, Clang, EKOPath & Intel C++ (but not MSVC);
So the disadvantage with macros is you need to know to use these to begin with, and that they aren't supported as widely.
One benefit is, in this case, you can use the same
square
function for many different types.