I've used a code base before that had a macro system for enabling and disabling sections of code. It looked something like the following:
#define IN_USE X
#define NOT_IN_USE _
#if defined( WIN32 )
#define FEATURE_A IN_USE
#define FEATURE_B IN_USE
#define FEATURE_C NOT_IN_USE
#elif defined( OSX )
#define FEATURE_A NOT_IN_USE
#define FEATURE_B NOT_IN_USE
#define FEATURE_C IN_USE
#else
#define FEATURE_A NOT_IN_USE
#define FEATURE_B NOT_IN_USE
#define FEATURE_C NOT_IN_USE
#endif
Then the code for the features would look like:
void DoFeatures()
{
#if USING( FEATURE_A )
// Feature A code...
#endif
#if USING( FEATURE_B )
// Feature B code...
#endif
#if USING( FEATURE_C )
// Feature C code...
#endif
#if USING( FEATURE_D ) // Compile error since FEATURE_D was never defined
// Feature D code...
#endif
}
My question (the part I don't remember) is how to define the 'USING' macro so that it errors if the feature hasn't been defined as 'IN_USE' or 'NOT_IN_USE'? Which could be the case if you forget to include the correct header file.
#define USING( feature ) ((feature == IN_USE) ? 1 : ((feature == NOT_IN_USE) ? 0 : COMPILE_ERROR?))
Your example already achieves what you want, since #if USING(x)
will produce an error message if USING
isn't defined. All you need in your header file is something like
#define IN_USE 1
#define NOT_IN_USE 0
#define USING(feature) feature
If you want to be sure that you also get an error just for doing something like
#if FEATURE
or
#if USING(UNDEFINED_MISPELED_FEETURE)
then you could do, say,
#define IN_USE == 1
#define NOT_IN_USE == 0
#define USING(feature) 1 feature
but you won't be able to prevent such misuse as
#ifdef FEATURE
The following works. It will give you compile error for FEATURE_D. If you comment out the code for FEATURE_D, then it will execute code for FEATURE_A and FEATURE_B. The code is pretty much self-explanatory. Instead of checking whether FEATURE_D or others are defined inside DoFeatures function, you can just put them inside an if block. In that way, the compiler will try to execute the code block. If it is 1, then the code inside if block will get executed; in case of 0, it will not get executed. And if it is never defined, then will get a compile error.
#include <stdio.h>
#define IN_USE 1
#define NOT_IN_USE 0
#define FEATURE_A IN_USE
#define FEATURE_B IN_USE
#define FEATURE_C NOT_IN_USE
void DoFeatures()
{
if(FEATURE_A){
// Feature A code...
printf("Feature A\n");
}
if(FEATURE_B){
// Feature B code...
printf("Feature B\n");
}
if(FEATURE_C){
// Feature C code...
printf("Feature C\n");
}
if(FEATURE_D) {// Compile error since FEATURE_D was never defined
// Feature D code...
printf("Feature D\n");
}
}
int main(int argc, char **argv)
{
DoFeatures();
return 0;
}
Just don't define it if it is not in use
#if defined( WIN32 )
#define FEATURE_A
#define FEATURE_B
#else if defined( OSX )
#define FEATURE_C
#else
#endif
Then In you code:
void DoFeatures()
{
#ifdef FEATURE_A
// Feature A code...
#endif
#ifdef FEATURE_B
// Feature B code...
#endif
#ifdef FEATURE_C
// Feature C code...
#endif
#ifdef FEATURE_D // Compile error since FEATURE_D was never defined
// Feature D code...
#endif
}
Couldn't you just use another group of #ifdef
s?
#if defined(WIN32)
#define FEATURE_A
#define FEATURE_B
#elif defined (OSX)
#define FEATURE_C
#endif
// ...
#if defined(FEATURE_A)
do_a();
#endif
etc.
#define IN_USE 1
//#define NOT_IN_USE _ //Not required
#if defined( WIN32 )
#define FEATURE_A IN_USE
#define FEATURE_B IN_USE
#define FEATURE_C NOT_IN_USE
#elif defined( OSX )
#define FEATURE_A NOT_IN_USE
#define FEATURE_B NOT_IN_USE
#define FEATURE_C IN_USE
#else
#define FEATURE_A NOT_IN_USE
#define FEATURE_B NOT_IN_USE
#define FEATURE_C NOT_IN_USE
#endif
#define USING( feature ) feature
And then your code
How about something like this?
#define IN_USE 1
#define NOT_IN_USE 0
#if defined( WIN32 )
#define FEATURE_A IN_USE
#define FEATURE_B IN_USE
#define FEATURE_C NOT_IN_USE
#elif defined( OSX )
#define FEATURE_A NOT_IN_USE
#define FEATURE_B NOT_IN_USE
#define FEATURE_C IN_USE
#else
#define FEATURE_A NOT_IN_USE
#define FEATURE_B NOT_IN_USE
#define FEATURE_C NOT_IN_USE
#endif
#define USING(f) ((f == IN_USE) ? 1 : (f == NOT_IN_USE) ? 0 : (f))
#include <stdio.h>
void DoFeatures()
{
#if USING( FEATURE_A )
// Feature A code...
printf("Feature A\n");
#endif
#if USING( FEATURE_B )
// Feature B code...
printf("Feature B\n");
#endif
#if USING( FEATURE_C )
// Feature C code...
printf("Feature C\n");
#endif
#if defined( FEATURE_D ) // Compile error since FEATURE_D was never defined
// Feature D code...
printf("Feature D\n");
#else
#error FEATURE_D not defined.
#endif
}
int main(int argc, char **argv)
{
DoFeatures();
return 0;
}
For the compilation error, I have no idea how to integrate it into the macro. It would be appreciated if somebody could shed us some light. :P