Many of the comments here are useful and describe the practical aspects of macro usage. However, I noticed a lack of detailed explanation regarding the semantics, so I hope my comment helps clarify additional details.
Functions:
- Function arguments are expressions that are fully evaluated before being passed to the function.
- Functions execute at runtime and can return a value after performing computations.
Macros:
- Macros operate at the preprocessing stage, where the preprocessor replaces the macro invocation with its definition.
- Arguments passed to a macro are not evaluated immediately; instead, they are directly substituted into the macro body as-is.
- Evaluation happens after substitution, during the compilation of the expanded code.
- To mimic the behavior of functions (where arguments are evaluated first), you must manually evaluate arguments before passing them to the macro.