cc-preprocessormetaprogramming

Is it possible to trigger a #if macro if two or more definitions are defined?


For instance, imagine you want to enable only one compilation target so you do something like this:

// uncomment ONE of these #defines to compile for a specific target
#define TARGET_1
#define TARGET_2

#if !defined(TARGET_1) && !defined(TARGET_2) // none defined
#error "You MUST select a target platform in target_platform.h"
#elif defined(TARGET_1) && defined(TARGET_2) // too many defined
#error "You must select ONLY ONE target platform target_platform.h"
#endif 

This works fine. And the #if scales well. However this second conditional in the #elif doesn't scale well to multiple targets as the conditional logic starts to get very complex. Thus, is there a way to scale this with some #if condition that we can check if at least two or more are defined for the second case? For instance, if I had 10 targets, this becomes very cumbersome to write, update, and maintain if I have to manually write all the conditional logic(or worse, someone else has to come back and understand it later)

I've tried looking at the syntax of #if, #elif, #define, Defined(), #ifdef, and #ifndef, but not of them seem to lend themselves to a cleaner way of doing this? At least, not that I can think of. But #if has gotten me the closest.


Solution

  • defined is an operator that evaluates to 0 or 1, so all you need, if you stll want this rather than Brad Lanam’s method is:

    …
    #elif 1 < defined TARGET_1 + defined TARGET_2 + defined TARGET_3 + …
        #error "You must select ONLY ONE target platform in target_platform.h"
    #endif
    

    You could actually combine both tests:

    #if 1 != defined TARGET_1 + defined TARGET_2 + defined TARGET_3 + …
        #error "You must select EXACTLY ONE target platform in target_platform.h"
    #endif