【问题标题】:C Macros: Function factories, why the macro don't works only in one case?C 宏:函数工厂,为什么宏仅在一种情况下不起作用?
【发布时间】:2010-12-07 22:59:50
【问题描述】:

我写了这两个宏:


// Magic Assert Equal Atomic constructor generator
#define _GENERIC_ASSERT_EQ_ATOMIC_CONSTRUCTOR_(n, N, W, tt) \
assert_data_t *assert_eq_##n##_constructor (tt a, tt b, int passed) {          \
    return assert_data_constructor (_ASSERT_EQ_##N##_, passed, W(a), W(b));    \
}

// Magic Assert Equal Vector constructor generator
#define _GENERIC_ASSERT_EQ_VECTOR_CONSTRUCTOR_(n, N, W, tt) \
assert_data_t *assert_eq_##n##_vector_constructor                              \
  (tt * a, tt * b, int n, int passed) {                                        \
    return assert_data_constructor                                             \
      (_ASSERT_EQ_##N##_VECTOR_, passed, W##Vector(a, n), W##Vector(b, n));    \
}

第一个宏运行良好(在我尝试过的情况下):


_GENERIC_ASSERT_EQ_ATOMIC_CONSTRUCTOR_(int, INT, Int, int)
_GENERIC_ASSERT_EQ_ATOMIC_CONSTRUCTOR_(flt, FLT, Flt, float)
_GENERIC_ASSERT_EQ_ATOMIC_CONSTRUCTOR_(dbl, DBL, Dbl, double)
_GENERIC_ASSERT_EQ_ATOMIC_CONSTRUCTOR_(complex_flt, COMPLEX_FLT, ComplexFlt, complex float)
_GENERIC_ASSERT_EQ_ATOMIC_CONSTRUCTOR_(complex_dbl, COMPLEX_DBL, ComplexDbl, complex double)
_GENERIC_ASSERT_EQ_ATOMIC_CONSTRUCTOR_(str, STR, Str, char *)

但第二个宏...在“int”情况下效果不佳(使用 float 和 double yes):


_GENERIC_ASSERT_EQ_VECTOR_CONSTRUCTOR_(int, INT, Int, int) // Here i have an error
_GENERIC_ASSERT_EQ_VECTOR_CONSTRUCTOR_(flt, FLT, Flt, float)
_GENERIC_ASSERT_EQ_VECTOR_CONSTRUCTOR_(dbl, DBL, Dbl, double)

gcc 显示的错误是:

unitarium4c.c:115:错误:声明说明符中有两种或多种数据类型 unitarium4c.c:在函数“assert_eq_int_vector_constructor”中: unitarium4c.c:115:错误:参数名称省略 unitarium4c.c:115:错误:“int”之前的预期表达式 unitarium4c.c:115:错误:“int”之前的预期表达式

:p 我不明白为什么会出现这个错误。 (如果我复制宏并展开它,它在“int”情况下运行良好)。

提前致谢:)。

【问题讨论】:

    标签: c macros


    【解决方案1】:

    试试

    // _GENERIC_ASSERT_EQ_VECTOR_CONSTRUCTOR_(int, INT, Int, int) // Here i have an error
       _GENERIC_ASSERT_EQ_VECTOR_CONSTRUCTOR_(integer, INT, Int, int)
    //                                   _____^^^^^^^_____
    

    原始宏的扩展会创建

    assert_data_t *assert_eq_int_vector_constructor                              \
      (int * a, int * b, int int, int passed) {                                        \
    /* __________________^^^^^^^__ */
        return assert_data_constructor                                             \
          (_ASSERT_EQ_INT_VECTOR_, passed, IntVector(a, n), IntVector(b, n));    \
    }
    

    您还可以告诉 gcc 在扩展宏后停止“编译”并检查生成的代码。试试

    gcc -E 源码

    【讨论】:

      【解决方案2】:

      你在宏体中有一个宏参数n和一个函数参数int n,所以它变成了int int

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-12
        • 2021-12-08
        • 2017-11-26
        • 2010-12-29
        • 1970-01-01
        相关资源
        最近更新 更多