C Preprocessor tricks, tips, and idioms

https://lobste.rs/rss Hits: 22
Summary

Basic Pattern Matching The ## operator is used to concatenate two tokens into one token. This is provides a very powerful way to do pattern matching. Say we want to write a IIF macro, we could write it like this: #define IIF ( cond ) IIF_ ## cond #define IIF_0 ( t , f ) f #define IIF_1 ( t , f ) t However there is one problem with this approach. A subtle side effect of the ## operator is that it inhibits expansion. Heres an example: #define A () 1 //This correctly expands to true IIF ( 1 )(true, false) // This will however expand to IIF_A()(true, false) // This is because A() doesn't expand to 1, // because its inhibited by the ## operator IIF ( A ())(true, false) The way to work around this is to use another indirection. Since this is commonly done we can write a macro called CAT that will concatenate without inhibition. #define CAT ( a , ...) PRIMITIVE_CAT(a, __VA_ARGS__) #define PRIMITIVE_CAT ( a , ...) a ## __VA_ARGS__ So now we can write the IIF macro(its called IIF right now, later we will show how to define a more generalized way of defining an IF macro): #define IIF ( c ) PRIMITIVE_CAT(IIF_, c) #define IIF_0 ( t , ...) __VA_ARGS__ #define IIF_1 ( t , ...) t #define A () 1 //This correctly expands to true IIF ( 1 )(true, false) // And this will also now correctly expand to true IIF ( A ())(true, false) With pattern matching we can define other operations, such as COMPL which takes the complement: #define COMPL ( b ) PRIMITIVE_CAT(COMPL_, b) #define COMPL_0 1 #define COMPL_1 0 or BITAND : #define BITAND ( x ) PRIMITIVE_CAT(BITAND_, x) #define BITAND_0 ( y ) 0 #define BITAND_1 ( y ) y We can define increment and decrement operators as macros: #define INC ( x ) PRIMITIVE_CAT(INC_, x) #define INC_0 1 #define INC_1 2 #define INC_2 3 #define INC_3 4 #define INC_4 5 #define INC_5 6 #define INC_6 7 #define INC_7 8 #define INC_8 9 #define INC_9 9 #define DEC ( x ) PRIMITIVE_CAT(DEC_, x) #define DEC_0 0 #define DEC_1 0 #define DEC_2 1 #define DEC_3 2 #define DEC_4 3 #d...

First seen: 2026-03-27 14:27

Last seen: 2026-03-28 12:39