Что это значит? #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;
}
Оператор ## берет два отдельных токена и вставляет их вместе в один токен. Полученный токен может быть именем переменной, именем класса или любым другим идентификатором.