What does this mean? #define TIMER_PASTE_B(lft,t,rgt) lft##t##_##rgt

84 Views Asked by At

I found the following function definition in the ATTiny85 tone core library. I cannot figure it out what does that mean, or how it works. It is used very often to create function names, but not sure how the syntax works.

Here is a trace back that I did on the function. There are many definition over definitions:

First instance:

 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...

then I trace the function tonetimer_ to be defined as:

#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 )

Then I found TIMER_PASTE_A function defined as:

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

finally I found the definition for TIMER_PASTE_B as:

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

This is where I got stuck. I could not follow that syntax. I was fine making simple substitutions. However, the ## trows me off.

So after making substitution, I can see the final command be something like this:

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

but not sure how that function will be execute it. This is not a definition neither a function.

does anyone has any idea?

Thank you.

2

There are 2 best solutions below

2
On BEST ANSWER

## is the concatenation

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

The preprocessor expands the definition to the concatenation of lft, t, _ and rgt.

For instance

TIMER_PASTE_B(ABC,DEF,GHI) 

would concatenate the tokens ABC, DEF, GHI and _ to

ABCDEF_GHI

Edit

Say you define TIMER_TO_USE_FOR_TONE to be timer 3, for instance

#define TIMER_TO_USE_FOR_TONE 3

the result would be

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

The ## operator takes two separate tokens and pastes them together to form a single token. The resulting token could be a variable name, class name or any other identifier.