This is what my #define
macro looks like:
#define CUSTOM_COMPARATOR(table, column, a, b) \
do { \
const struct db_##table *row1 = a; \
const struct db_##table *row2 = b; \
\
/* Insert lot of code here with multiple row->##column usage */ \
return strcmp(row1->##column->name1, row2->##column->name2); \
} while (0)
I have to generate multiple definitions based on different table and column types. These definitions are preprocessed and called in multiple functions:
static int
db_table_sometable_somecolumn_comparator(const void *a, const void *b) {
CUSTOM_COMPARATOR(sometable, somecolumn, a, b);
}
static int
db_table_someothertable_someothercolumn_comparator(const void *a, const void *b) {
CUSTOM_COMPARATOR(someothertable, someothercolumn, a, b);
}
Basically I want to avoid the duplication of code inside CUSTOM_COMPARATOR
. When I compile this gcc complains that pasting "->" and "somecolumn" does not give a valid preprocessing token
which is understandable since ->
breaks the token. It works on db_##table
because it produces a single token.
Nonetheless, is there any way I can achieve this? I have like 10s of table/columns with just name change but share the same logic mentioned in CUSTOM_COMPARATOR
which is also 50 LoC in real.
Don't try to paste the column name to make a new token. You can simply do this:
return strcmp(row1->column->name1, row2->column->name2);
This is accepted by the preprocessor, and expands to, e.g. with gcc -E
:
static int
db_table_sometable_somecolumn_comparator(const void *a, const void *b) {
do { const struct db_sometable *row1 = a; const struct db_sometable *row2 = b; return strcmp(row1->somecolumn->name1, row2->somecolumn->name2); } while (0);
}
static int
db_table_someothertable_someothercolumn_comparator(const void *a, const void *b) {
do { const struct db_someothertable *row1 = a; const struct db_someothertable *row2 = b; return strcmp(row1->someothercolumn->name1, row2->someothercolumn->name2); } while (0);
}
which is perfectly valid C.