I’d like to know if I can trigger #error if value of multiple enum are bad. For example I have this enum
enum config_choice {
YES,
NO
};
enum config_choice PARAM_1 = YES;
enum config_choice PARAM_2 = NO;
enum config_choice PARAM_3 = YES;
....
For example I’d like to have something like this
if(PARAM_1 == YES && (PARAM_2 == YES || PARAM_3 == YES) ){
#error "Bad configuration!!!"
}
Enum values will never change during runtime.
>Solution :
Per se such things are not supported – but you can still achieve compilation breaking by using a little trick for: Creating or defining an array of negative size!
This can look as follows (general case):
typedef int StaticCheck[-(theFailureCondition)];
// or:
typedef int StaticCheck[-!(theSuccessCondition)];
So for your specific example:
enum config_choice
{
YES,
NO
};
// though you need compile time constants for (!):
#define PARAM_1 YES
#define PARAM_2 NO
#define PARAM_3 YES
// enum config_choice PARAM_X = ...;
// is not; not even if you apply const to:
// enum config_choice const PARAM_Y = ...;
typedef int ConfigCheck[-(PARAM_1 == YES && (PARAM_2 == YES || PARAM_3 == YES))];
This makes the compilation fail (your goal), though resulting error messages are pretty unfortunate, of course.
If you need many such checks you might create a macro for, e.g.
#define STATIC_ASSERT(CONDITION) \
typedef int CONCAT(StaticCheck_, __LINE__)[-!(CONDITION)]
// note the naming: we want to a s s e r t, thus want to fail on opposite value
#define CONCAT(X, Y) CONCAT_(X, Y) // classic token concatenation...
#define CONCAT_(X, Y) X ## Y
Of course you cannot define more than one test on the same line, but that wouldn’t be recommended anyway (even less readable error messages).
For your specific case:
STATIC_ASSERT(PARAM_1 != YES || (PARAM_2 != YES && PARAM_3 != YES));
// (inverted condition, see above)
Demonstration (with macro) on godbolt.