Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to "#define" multiple values then "#if" them in C

The following code does not work but demonstrates what I want to do

#define TESTINGMACRO 2 | 3

#if TESTINGMACRO & 1 //Should be inactive
#endif

#if TESTINGMACRO & 2 //Should be active
#endif

#if TESTINGMACRO & 3 //Should be active
#endif

Another alternative:

#define TESTINGMACRO 2, 3

#if TESTINGMACRO == 1 //Should be inactive
#endif

#if TESTINGMACRO == 2 //Should be active
#endif

#if TESTINGMACRO == 3 //Should be active
#endif

I know an enum or an array would work too however some preprocessor blocks contains #includes that might not build. Using preprocessor code allows for testing the rest of the file.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I also know I can do the following but this will be a large file so a single central macro would be cleaner:

#define TESTINGMACRO2
#define TESTINGMACRO3

#ifdef TESTINGMACRO1 //Should be inactive
#endif

#ifdef TESTINGMACRO2 //Should be active
#endif

#ifdef TESTINGMACRO3 //Should be active
#endif

Edit: Just FYI in the first scenario all preprocessor blocks are active in practice. So doing 2 | 3 will activate & 1 as well. This is the case for the second code snippet too. This is not what I want, only 2 and 3 should be active when 2|3.

Edit2: I ended up doing:

#define BIT(n)  (1<<n)

#define TESTINGMACRO  ( BIT(2) | BIT(3) )

#if TESTINGMACRO & BIT(1) //Inactive
#endif

#if TESTINGMACRO & BIT(2) //Active
#endif

#if TESTINGMACRO & BIT(3) //Active
#endif

Format wise this is closest to my original and in my opinion quite readable. Thanks for all the help

>Solution :

You can use bit fields — but then you need to do it properly:

  • Define the values as distinct powers of two. Instead of 1, 2, 3, …, use 1 << 0, 1 << 1, 1 << 2, … (aka. 1, 2, 4 …).

  • Fix the operator precedence by adding parentheses. Remember that macros are expanded via textual replacement.

#define TESTINGMACRO ((1 << 1) | (1 << 2))

#if TESTINGMACRO & (1 << 0) //Should be inactive
#endif

#if TESTINGMACRO & (1 << 1) //Should be active
#endif

#if TESTINGMACRO & (1 << 2) //Should be active
#endif

That said, I would generally recommend using separate feature macros instead, the resulting code is more readble.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading