You can use the ternary operator, but keep in mind that for objects with a static or thread-local storage class, the initializer expression must be a compile-time constant:
const int bar = 42; #define BAR 42 #if 0 const int foo = bar ? 1 : 2; #else const int foo = BAR ? 1 : 2; #endif void fn(void) { const int foo = bar ? 1 : 2; #if 0 static const int stc_foo = bar ? 1 : 2; #else static const int stc_foo = BAR ? 1 : 2; #endif }
The reason the if-else statement cannot be used for initialization is because it will require quite significant changes to the C grammar to resolve it, and this will probably complicate C's grammar and semantics significantly.
Basically, instead of just checking that the declarator is followed by the = and initializer expression, and that this initializer expression is constant, the compiler needs to remember every static / thread-local variable that has initialized, and then looks for unconditionally executable branches parsed during compilation, which follow its assignment to it and use them for initialization.
In addition, statements must be allowed in the file area (statements are not allowed in the file area in the current grammar C) and checked for restrictions on content capacity and memory that are limited to writing to translation unit global variables. Alternatively, they can be implicitly turned into global constructors, but this will lead to additional problems, such as arranging the constructor between compilation units (which would be difficult to resolve if the constructor generation was implicit), the need for implementations to support the global constructor in the first place or the blurring of currently quite simple performance characteristics of static variable assignments.
source share