Макросы C: Фабрики функций, почему макрос не работает только в одном случае? - PullRequest
1 голос
/ 08 декабря 2010

я написал эти два макроса:


// 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: error: two or more data types in declaration specifiers
unitarium4c.c: In function ‘assert_eq_int_vector_constructor’:
unitarium4c.c:115: error: parameter name omitted
unitarium4c.c:115: error: expected expression before ‘int’
unitarium4c.c:115: error: expected expression before ‘int’

: p Я не понимаю, почему появляется эта ошибка. (Если я скопирую макрос и разверну его, он хорошо работает в случае с int).

Заранее спасибо :).

Ответы [ 2 ]

4 голосов
/ 08 декабря 2010

Попробуйте

// _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 source
3 голосов
/ 08 декабря 2010

У вас есть макро-параметр n и функциональный параметр int n в теле макроса, поэтому он становится int int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...