sábado, 18 de novembro de 2006

ANSI C Conditional operator grammar analysis.

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


Hum, 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: b
And, 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'.

Nenhum comentário:

Quem sou eu

Minha foto
I used to work with embedded software and digital design. Now my career is about to turn in a complete different direction ...