A friend I meet at C language lists send me a question about compiling problems with
the conditional operator.
These lines:
int main(){
int a = 10 , b ;
a >= 5 ? b =100: b=200;
}Did not compile or give a warning, depending on the compiler, of course. But with a little change:
int main(){
int a = 10 , b ;
a >= 5 ? b =100: (b=200);
}The warnings/erros stoped. The question is why?
Well, before start, I change the code a little ...
int main(){
int a = 10 , b ;
a >= 5
? b =100
: b=200;
}... and a compile it again (with lcc-wi32). The error where related to the last assignment.
By that time, I was aware that I would need to search for the grammar definition of this operator. In the absence of a ANSI C spec, I search the "The ANSI C Language", Kernighan & Ritchie, whose had an Appendix with ANSI C grammar and comments.
Section A.7.16 the grammar defines the conditional operator as:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expressionHum, the third argument is not an expression. It is in fact, redefined as a conditional expression. Probably, in order to allow chained use. Following the definitions, the parser will end to an primary-expression. The primary expression will the resolve, as the a is an identifier.
The compiler will evaluate this as an conditional expression:
a >= 5 ? b =100: bAnd, will encounter the assignment and will interpreter this as an attempt to change
the conditional-expression result. Witch is invalid of course. Or, something like that:
(a >= 5 ? b =100: b) = 200;I tried it in my compiler, and it returned the same error.
Okay, but and about the second try? Why it works? Simple: As the parenthesis are around, it will force the expression b = 200 to be evaluated first.
About the C grammar, you can find it also at the internet at the site
http://www.lysator.liu.se/c/ANSI-C-grammar-y.html#conditional-expression, as a YACC grammar definition file. Starting from the beginning of the conditional expression, we have:
conditional_expression -> logical_or_expression -> logical_and_expression -> inclusive_or_expression -> exclusive_or_expression -> and_expression -> equality_expression -> relational_expression -> shift_expression -> additive_expression -> multiplicative_expression -> cast_expression -> unary_expression -> postfix_expression -> primary_expression and finally the IDENTIFIER. At the example give above, it will be the 'b'.