代码之家  ›  专栏  ›  技术社区  ›  tcpip

使用C标记粘贴器避免代码重复

  •  2
  • tcpip  · 技术社区  · 2 周前

    这是我的 #define 宏看起来像:

    #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)
    

    我必须基于不同的表和列类型生成多个定义。这些定义在多个函数中进行预处理和调用:

    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);
    }
    

    基本上我想避免内部代码的重复 CUSTOM_COMPARATOR 。当我编译这个gcc时,它抱怨说 pasting "->" and "somecolumn" does not give a valid preprocessing token 这是可以理解的,因为 -> 破坏令牌。它适用于 db_##table 因为它只生成一个令牌。

    尽管如此,我有办法做到这一点吗?我有大约10个表/列,只更改了名称,但共享中提到的相同逻辑 客户_比较器 实际也是50 LoC。

    1 回复  |  直到 2 周前
        1
  •  3
  •   pmacfarlane    2 周前

    不要试图粘贴列名以生成新的标记。您可以简单地执行以下操作:

            return strcmp(row1->column->name1, row2->column->name2);
    

    这被预处理器接受,并扩展到例如 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);
    }
    
    

    这是完全有效的C。