Pasindu wijesinghe
Pasindu wijesinghe

Reputation: 33

Preprocessor directives in C : macros using __LINE__

I find it difficult to understand the working of a macro defined with the help of preprocessor directives.

The macro,

TRXEM_SPI_BEGIN()

is defined with the help of two preprocessor directives refereed from two header files. Firstly, I wish to state the declaration of the said macro.

#define TRXEM_SPI_BEGIN() st( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; NOP();)

As the declaration of macro st () is missing here, I found it defined in a different header file and ti is shown below.

#define st(x) do { x } while (__LINE__ == -1)

Now after combining two macros, the true definition of macro TRXEM_SPI_BEGIN() must be,

#define TRXEM_SPI_BEGIN() do {

( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; NOP(); )

} while (__LINE__ == -1)

This code is written to work inside a microcontroler where TRXEM_PORT_OUT, RXEM_SPI_SC_N_PIN are memory mapped registers and NOP initiates an instruction cycle that does nothing.

As per my understanding, __LINE__ means the line of code in the c file where __LINE__ lies. That line can never be equal to -1. i.e. this loopmust always be running only once provided the __LINE__ can never be placed in -1 place in a .c file. Simply put, -1 can never be the value of __LINE__.

Therefore, I believe a do while() loop here is unnecessary and the same output could have been achieved by simply without using any looping.

I do not understand the functioning of this macro. I would so much appreciate if someone could elaborate on it.

Upvotes: 0

Views: 581

Answers (1)

Mohit Jain
Mohit Jain

Reputation: 30489

As per my understanding, means the line of code in the c file where __LINE__ lies. That line can never be equal to -1. i.e. this loopmust always be running only once provided the __LINE__ can never be placed in -1 place in a .c file. Simply put, -1 can never be the return value to a __LINE__.

Your understanding is exactly correct here. It is there to make sure the code runs exactly once.

Think of following scenario:

#define BAZ foo();bar();

Now if you do

if(some_cond) BAZ;

This is equivalent to:

if(some_cond) foo();
bar();

Which is most possibly not something you want. So you change it to:

#define BAZ {foo();bar();}

This works fine if written as if(some_cond) foo() else wow(); but would fail compilation if written as if(some_cond) foo(); else wow();

So you define BAZ as

/* No semicolon at end */
#define BAZ do {foo();bar();} while(condition_which_is_always_false)

And you can now write the natural code with intuitive semicolon at end.

In your case, condition_which_is_always_false is __LINE__ == -1

Upvotes: 1

Related Questions