I'm working with a moderately sized embedded C++ project that has a number of configurations for different target products. There are a good number of macros that get set for various configuration items in the different configurations and I'm trying to make that system as error-proof as possible.
Initially, I was just doing the standard thing:
#define CFG_FOO
#ifdef CFG_FOO
<code here>
#endif
but I'm always afraid I'm going to mistype a macro name in an ifdef and have a hard to find bug, because this evaluates to false without error:
#ifdef CFG_FOOO
So, I changed all the macros to this format, which requires that the macro in question be defined, defining all the ones that I want to evaluate as false to 0:
#define CFG_FOO() (1)
#define CFG_BAR() (0)
#if CFG_FOO()
<code is active>
#endif
#if CFG_BAR()
<code is inactive>
#endif
// Produces error, as desired:
#ifdef CFG_FOOO()
#endif
This was good, except that then if I accidentally enter the following (which I found I do all the time, just out of habit) it is true and the contained code is compiled:
#ifdef CFG_BAR
<this is active>
#endif
So I'm looking for a solution that:
NOTE: I'm aware of the -Wundef option for gcc, but I don't believe that really helps, as the accidental #ifdef situation is still present.
Instead of repeatedly do
#if CFG_FOO()
<code is active>
#endif
since C99 or C++11, you might have once (per config)
#if CFG_FOO() // or #ifdef CFG_FOO
# define WITH_FOO(...) __VA_ARGS__
#else
# define WITH_FOO(...) /*Empty*/
#endif
And then
WITH_FOO(
<code is active>
)
Note:
My best recommendation is never get yourself into a situation where CFG_FOO
is valid, CFG_BAR
is valid, but both together is not valid.
We can do better by simply avoiding this problem. Specialized form for a switch ladder. CFG
is a bad prefix but I'm assuming it's an artifact of minimalization and you simply will have a better one.
modeswitch.h:
#define CFGMODE_FOO 1
#define CFGMODE_BAR 2
header.h:
#if CFG == CFGMODE_FOO
#elif CFG == CFGMODE_BAR
#else
#error CFG has unsupported value
#endif
program.c
#include "modeswitch.h"
#define CFG CFGMODE_FOO
#include "header.h"
If I read this wrong and you're not using this stuff in .h
files than I wonder why you have both C and C++ tags but just inline the stuff and it will still work.
My understanding is there's enough power in ##
that there's a way to get rid of the pre-header but it's so hard that it doesn't meet any reasonable definition of foolproof.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With