3

I'm studying the source code of FreeRTOS. I found this snippet: https://github.com/TheKK/myFreeRTOS/blob/master/include/list.h#L268

#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                        \
{                                                                                           \
    List_t * const pxConstList = ( pxList );                                                \
    /* Increment the index to the next item and return the item, ensuring */                \
    /* we don't return the marker used at the end of the list.  */                          \
    ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                            \
    if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )  \
    {                                                                                       \
        ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                        \
    }                                                                                       \
    ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;                                          \
}

I know that ( pxConstList )->pxIndex means access the data of pointer variable pxConstList. But I'm wondering what is the meaning of surround a variable with parenthesis only?

That is:

List_t * const pxConstList = ( pxList );
                             ~~~~~~~~~~

and

( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;
~~~~~~~~~~

Thanks.

Veck Hsiao
  • 591
  • 2
  • 8
  • 20

2 Answers2

4

These variables are actually parameters to a macro. The parenthesis are necessary because a parameter may be an expression that wouldn't fit properly in context without them.

Consider for example this macro:

#define SQUARE(x) x*x

If you called this macro like this:

SQUARE(4+5)

You would get:

4+5*4+5

Because * has higher precedence than +, this would evaluate to 29 instead of the expected 81. If the macro were defined like this:

#define SQUARE(x) (x)*(x)

Then the above would expand to:

(4+5)*(4+5)

Which would evaluate to 81.

So to summarize, it's recommended to always parenthesize macro parameters to avoid these types of issues.

dbush
  • 205,898
  • 23
  • 218
  • 273
1

Notice that listGET_OWNER_OF_NEXT_ENTRY is a macro (not a function), i.e. pxTCB and pxList will be copy-pasted. if they are expressions you have to put parenthesis around them. why? see here C macros and use of arguments in parentheses

hazirovich
  • 170
  • 7