I’ve learned a lot of crazy things about C and C++ in the last few years, as far as parsing goes. The one that’s always blown me away the most is that parsing C++ is undecidable: you can’t properly parse C++ without doing template instantiation, but template instantiation is turing-complete.
But every time I think I’ve gotten to the point where C and C++ can’t faze me anymore, I find something new. Like this, from the Wikipedia article about operator precedence in C and C++:
The binding of operators in C and C++ is specified (in the corresponding Standards) by a factored language grammar, rather than a precedence table. This creates some subtle conflicts. For example, in C, the syntax for a conditional expression is:logical-OR-expression ? expression : conditional-expression
while in C++ it is:logical-or-expression ? expression : assignment-expression
Hence, the expression:
e = a ? b : c = d
is parsed differently in the two languages. In C, this expression is parsed as:
e = ((a ? b : c) = d)
which is a semantic error, since the result of a conditional-expression is not an lvalue. In C++, it is parsed as:
e = (a ? b : (c = d))
which is a valid expression.
WHAT?? I had to try this out and determine whether it was true or some crazy Wikipedia anonymous editor who was trying to drive me mad. So I wrote the simple test program:
…and attempted to compile it first with gcc as a .c, then with g++ as a .cc, and sure enough:
The world is insane. Luckily Gazelle will be the sword in your right hand, your weapon against a world that conspires against your sanity.
Incidentally, it’s more and more clear that C++ is not a superset of C. Though it’s true enough that most people using the language don’t have to care, for language implementors the differences are significant.