19 ms·
I only saw the kind of macros you're probably thinking about (on the order of #define min(X, Y) ((X) < (Y) ? (X) : (Y))) in kbit.h, but I didn't look at the so
by ANTSANTS 14y ago
I only saw the kind of macros you're probably thinking about (on the order of #define min(X, Y) ((X) < (Y) ? (X) : (Y))) in kbit.h, but I didn't look at the source to all the components. What klib does seem to use the preprocessor quite a bit for, however, is implementing generic functions and datatypes -- in other words, since the only significant difference between the implementation of a linked list whose nodes have "payloads" of 2 bytes, and one where the payloads are twice as large is, at the language level, the size of the respective payloads, we would ideally like some kind of code generating "function" that will take a datatype of some size and produce an appropriate linked list implementation. C++'s function templates exist for this sole purpose, but in C, we have to abuse its preprocessor to get a similar result.
If you take a look at the source of klist.h, the preprocessor stuff is a bit hairy, but it basically leaves you with a "compile time function", KLIST_INIT, that takes a datatype and generates, via simple textual substitution, an implementation of a linked list where each node of the list carries a payload of that datatype. klib_test.c includes a simple usage case.
Just to be clear, the preprocessor is generating real functions (inline ones, but functions nonetheless), not simply textually inserting the appropriate list code every time you use one of the macros like kl_next(iter) defined at the end of klist.h.
Check out the GCC docs on macros (and particularly, the section on concatenation) to get a better understanding of how klib implements this.
http://gcc.gnu.org/onlinedocs/cpp/Macros.html http://gcc.gnu.org/onlinedocs/cpp/Macros.html
As for how "crazy" it is to do this with the preprocessor, it's just the most convenient alternative in C to manually copying and pasting a generic list implementation yourself and editing in the correct type information, so it's a fairly common practice. You'll know code that really abuses the preprocessor when you see it -- I would advise then to run.