Anand
Anand

Reputation: 25

Creating a macro with ## operator

Sorry I may be repeating a question asked previously, but I did not get the answer I am looking for. So Here is what I am trying to create:

typedef struct flags
{
    unsigned char flag0:1;
    unsigned char flag1:1;
    unsigned char flag2:1;
    unsigned char flag3:1;
    unsigned char flag4:1;
    unsigned char flag5:1;
    unsigned char flag6:1;
    unsigned char flag7:1;
}BFLAG;

typedef union
{
    unsigned char byte;
    BFLAG  bitflg;
}GENFLAG;

GENFLAG status_flag, hmi_flag;

Then I want to create macros to address specific bits as follows:

#define EDIT_PARAM      status_flag.bitflg.flag0    // l: Locked for editing, 0:Editable

#define HIDE_PARAM      status_flag.bitflg.flag1    // 1: parameter is hidden, 0:visible

#define LOCK_PARAM      hmi_flag.bitflg.flag0   // 1: Password Unlock, 0: locked 1.

etc.

So I want to be able to concatenate a common string such as "status_flag.bitflg.flag" using the ## operator with 0, 1, 2, 3 etc in each instance creating a new macro. But I want to use macros such as EDIT_INDEX for 0, HIDE_INDEX for 1 etc.

#define EDIT_INDEX  0
#define HIDE_INDEX  1

However if I use this directly in a macro such as

#define CONCAT(x, y)    x##y
#define EDIT_PARAM    CONCAT(status_flag.bitflg.flag, EDIT_INDEX)

All I get is the concatenation of the string on the left hand side with EDIT_INDEX as a string not the expanded macro as

status_flag.bitflg.flag0

What should I do if I want it to create the expansion as shown above? Any and all help will be sincerely appreciated. Sorry if my problem statement is found wanting.

I tried the following

#define CONCAT(x, y)    x##y
#define EDIT_PARAM    CONCAT(#status_flag.bitflg.flag, EDIT_INDEX)

It gives the output as "status_flag.bitflg.flagEDIT_INDEX", not "status_flag.bitflg.flag0" as intended.

Upvotes: 2

Views: 89

Answers (1)

Marco
Marco

Reputation: 7261

This is a known limitation of macro expansion in C.

It's generally worked around by using:

#define CONCAT1(x, y)    x##y
#define CONCAT(x, y)     CONCAT1(x, y)

Instead of just

#define CONCAT(x, y)    x##y

Explanation:

The combination of CONCAT() and CONCAT1() makes the preprocessor evaluate x and y before concatenating them.

Upvotes: 5

Related Questions