Что это значит? #define TIMER_PASTE_B(lft,t,rgt) lft##t##_##rgt

Я нашел следующее определение функции в базовой библиотеке тонов ATTiny85. Я не могу понять, что это значит или как это работает. Он очень часто используется для создания имен функций, но не уверен, как работает синтаксис.

Вот след, который я сделал на функции. Есть много определений над определениями:

Первый случай:

 void tone( uint8_t _pin, unsigned int frequency, unsigned long duration )
{
  tonetimer_(ocr_t)             ocr;
  tonetimer_(prescale_value_t)  csv;
  tonetimer_(cs_t)              csi; //and the function continue...

тогда я прослеживаю функцию tonetimer_, которая будет определена как:

#define tonetimer_(t)  TIMER_PASTE_A( timer, TIMER_TO_USE_FOR_TONE, t )
#define ToneTimer_(f)  TIMER_PASTE_A( Timer, TIMER_TO_USE_FOR_TONE, f )
#define TONETIMER_(c)  TIMER_PASTE_A( TIMER, TIMER_TO_USE_FOR_TONE, c )

Затем я нашел функцию TIMER_PASTE_A, определенную как:

#define TIMER_PASTE_A(lft,t,rgt)      TIMER_PASTE_B(lft,t,rgt)

наконец, я нашел определение для TIMER_PASTE_B как:

#define TIMER_PASTE_B(lft,t,rgt)         lft##t##_##rgt

Вот где я застрял. Я не мог следовать этому синтаксису. Я прекрасно делал простые замены. Тем не менее, ## сбивает меня с толку.

Итак, после подстановки я вижу, что последняя команда выглядит примерно так:

timer##TIMER_TO_USE_FOR_TONE##_##ocr_t      ocr;

но не уверен, как эта функция будет выполнять его. Это не определение и не функция.

у кого-нибудь есть идеи?

Спасибо.

2 ответа

Решение

## это конкатенация

#define TIMER_PASTE_B(lft,t,rgt)  lft##t##_##rgt

Препроцессор расширяет определение до объединения lft, t, _ а также rgt,

Например

TIMER_PASTE_B(ABC,DEF,GHI) 

объединит токены ABC, DEF, GHI и _ в

ABCDEF_GHI

редактировать

Скажем, вы определяете TIMER_TO_USE_FOR_TONE для таймера 3, например

#define TIMER_TO_USE_FOR_TONE 3

результат будет

void tone( uint8_t _pin, unsigned int frequency, unsigned long duration )
{
  timer3_ocr_t ocr;
  timer3_prescale_value_t csv;
  timer3_cs_t csi;
}

Оператор ## берет два отдельных токена и вставляет их вместе в один токен. Полученный токен может быть именем переменной, именем класса или любым другим идентификатором.

Другие вопросы по тегам