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.
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