Ошибка в конкатенации препроцессора C с переменной и функцией (динамическое индексирование в a для l oop) - PullRequest
0 голосов
/ 06 февраля 2020

Я запустил этот код в этом компиляторе

#define CCc(n) CC_##n
#define CC(n) CCc(n)
#define CC_1 (1,2)
#define CC_2 (3,4)
#define CALL_FUNCTION(xy) Coord(xy)
#define YES 1
#define NO 0
int Coord(x, y){
    if (x < 0.5 && y < 1.5){
            return YES;
    }
    return NO;
}


int main()
{
    for(int i = 1; i < 3; i++){
        CALL_FUNCTION(CC(i));
    }
    return 0;
}

и получил эту ошибку:

ошибка: использование необъявленного идентификатора 'CC_i '

Почему возникает эта ошибка? И как правильно этого достичь?

1 Ответ

1 голос
/ 06 февраля 2020

Вы не можете выполнять оценку времени выполнения / переменных в препроцессоре. Это требует токенов препроцессора времени компиляции. Поэтому вместо того, чтобы пытаться определить число #define на основе значений времени выполнения, вы должны собрать все константы времени компиляции в одном месте.

Обычный способ сделать это - "X макросы". В вашем случае это может выглядеть следующим образом:

#define CC_LIST \
/*  n  x  y  */ \
  X(1, 1, 2)    \
  X(2, 3, 4)    \

int main()
{
    #define X(n,x,y) (void) Coord(x, y);
      CC_LIST
    #undef X

    return 0;
}

Это расширяется до (void) Coord(1,2); (void) Coord(3,4);, так что это время развертывания l oop сорта.

В качестве альтернативы, если вы настаивайте на том, чтобы иметь макросы "CC_N", потому что они также необходимы для других целей, вы можете сделать это:

#define CC_LIST \
/*  n  */       \
  X(1)          \
  X(2)          \

#define CC(n) CC_##n
#define CC_1 1,2
#define CC_2 3,4

#define CALL_FUNCTION(...) (void) Coord(__VA_ARGS__);


int main()
{
  #define X(n) CALL_FUNCTION(CC(n))
    CC_LIST
  #undef X

  return 0;
}

Как вы можете сказать, трюки с макросами, такие как "X макросы", не легко читать и должны считаться последним средством. Используйте их только тогда, когда надлежащая перепроектировка программы невозможна, например, при обслуживании существующего кода.

...