Is using the tenary operator within array initalization with constants valid C99?
uint8_t foo[] = {bar? 9U:20U};
Yes, you may. Starting from the grammar production for an initalizer:
6.7.8 Initialization
initializer: assignment-expression { initializer-list } { initializer-list , } initializer-list: designation(optional) initializer initializer-list , designation(optional) initializer
The only relevant (in my opinion) constraint on the initializer in that section is that it must be a constant expression for objects with static storage duration:
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
Following it onward to the production of assignment-expression
, we see that
6.5.16 Assignment operators
assignment-expression: conditional-expression unary-expression assignment-operator assignment-expression
A conditional expression is a valid assignment expression as well. So it may appear as an initializer in an initializer list. The only thing left to check is that it can be a valid constant expression for objects with static storage duration.
6.6 Constant expressions
constant-expression: conditional-expression
With the following constraint and semantic paragraphs:
Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.
More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:
- an arithmetic constant expression,
- a null pointer constant,
- an address constant, or
- an address constant for an object type plus or minus an integer constant expression.
So all of the above makes for the following valid program:
#include <stdint.h>
#include <stdlib.h>
#define BAR 1
uint8_t foo[] = {BAR ? 9U:20U};
int main(void) {
int bar = rand();
uint8_t foo[] = {bar ? 9U:20U};
}
Furthermore, for objects with automatic storage duration, you aren't limited to constant expressions as the two sub-expressions of the conditional expression. They can refer to any object in scope as well.
No. From clang
:
example.c:4:15: warning: initializer for aggregate is not a compile-time
constant [-Wc99-extensions]
int foo[] = {bar? 9U:20U};
^~~~~~~~~~~
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With