Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional inside C macro?

Is there any way to do this conditional at compile time instead of at runtime?

"flag" will always be a constant. A() and B() are macros.

#define DEMO(flag, p) if (flag) A(p); else B(p)

Why do I want to do this? Because macro A may or may not exist, depending on the underlying hardware (macro A controls hardware on a microcontroller).

If DEMO is called with "flag" that evaluates to false, it doesn't matter - it should compile. But if DEMO is called with "flag" that evaluates to true, I want to see a build error.

ADDED:

The intended use is like this:

DEMO(true, p);  // this should cause a build error
DEMO(false, p); // this should compile OK
DEMO(0, p); // should be OK
DEMO(1 == 2, p); // should be OK
DEMO(1 == 1, p); // should cause a build error

The passed parameter is always a constant, but not always the same constant.

like image 414
nerdfever.com Avatar asked Aug 15 '15 02:08

nerdfever.com


1 Answers

Is there any way to do this conditional at compile time instead of at runtime?

Sure:

// add or remove this definition
#define flag

#if defined(flag)
   #define DEMO(p) A(p)
#else
   #define DEMO(p) B(p)
#endif

ADDED in response to OP's addition:

#define DEMOfalse(p) B(p)
#define DEMOtrue(p) A(p)
#define DEMO(flag,p) DEMO##flag(p)

This uses the "stringizing" operator (##) which replaces ##flag with the actual source code text you call the macro with.

DEMO(true,p) will expand to DEMOtrue(p), which expands to A(p). If you pass true and A is not defined, your build will fail.

DEMO(false,p) will expand to DEMOfalse(p), then B(p), which will build whether or not A is defined.


EDIT in response to OP's edit:

A macro cannot contain preprocessor statements (well, it can, but they won't processed by the preprocessor), so there's no way to put a compile time conditional in the macro, hence the approaches shown above.

like image 146
Mud Avatar answered Sep 19 '22 03:09

Mud