If your question is βwhy use multiple macro levels?β Then:
- why not? It is noteworthy that in the pre-C99 era without
inline . The canonical example was the era of the 1980s [t21>, which was (IIRC) at that time (SunOS3.2, 1987), documented as a macro, with a note on the man page telling (I forgot the details) that with some FILE* filearr[]; a getc(filearr[i++]) was wrong (IIRC, at that time there was no undefined behavior terminology). When you looked at some system headers (for example, <stdio.h> or any header included by it), you can find the definition of such a macro. And at that time (with computers running at only a few MHz, therefore a thousand times slower than today), getc should be a macro for efficiency reasons (since inline does not exist, and compilers did not do interprocedural optimizations , as they can do now) . Of course, you can use getc in your own macros. - Even today, some standards define macros. In particular, today the waitpid (2) system call document is
WIFEXITED and WEXITSTATUS as macros, and it is prudent to use #define some of your macros mix both of them. - The main thing is to understand the work of the C preprocessor and its deeply textual (so fragile) nature. This is explained in all the textbooks about C. Therefore, you need to understand what happens under the hoods.
- a rule of thumb with the modern era of C (i.e., C99 and C11) is to systematically prefer to have some
static inline function (defined in some header file) equivalent to a macro. In other words, #define some macro only when you cannot escape it. And I explicitly document this fact. - several macro levels (sometimes) increase code readability.
- macros can be tested with
#ifdef macroname , which is sometimes useful.
Of course, when you decide to define several levels of macros (I will not call them "recursive", read self-referencing macros ) you need to be very careful and understand what happens to all of them (combined and separately). It is useful to look into the pre-processed form.
By the way, to debug complex macros I sometimes do
gcc -C -E -I/some/directory mysource.c | sed 's:^#://
then I look at mysource.i and sometimes even compile it, perhaps as gcc -c -Wall mysource.i , to get warnings that are in the pre-processed form of mysource.i (which I can check in the emacs editor). The sed command "comments" lines starting with # that set the source location (Γ la #line ) .... Sometimes I even do indent mysource.i
(in fact, I have a special rule for my Makefile )
Does LPM have the __ prefix proper?
By the way, names starting with _ (standard and conditionally) are reserved for implementation. Basically, you are not allowed to have your names starting with _ , so there can be no collision.
Note that the __LPM_classic__ macro uses statement-expr extension ( GCC and Clang )
See also other programming languages. Common Lisp has a completely different macro model (and much more interesting). Read about hygiene macros . My personal regret is that the C preprocessor never developed to be much more powerful (and Scheme-like). Why this did not happen (imagine that the C preprocessor can call the Guile code to expand the macro!), Probably for sociological and economic reasons.
You still need to sometimes use some other preprocessor (like m4 or GPP ) to generate the C code. See autoconf .
source share