How to read & understand C & C++ Standards and the language grammar used therein?
I often find C and C++ Standards difficult to read and understand, even the simple English sentences and their wordings give terrible experience. On the top of it, the language grammar is totally hell. I'm sure many share the same feeling, at least my friends do.
I would like to understand it by some examples. Lets begin with this (which tries to explain why the conditional expression in C++
is different from the conditional expression in C
: (quoted from wikipedia)
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 < d ? a++ : a = d
is parsed differently in the two languages. In C, this expression is a syntax error, but many compilers parse it as:
e = ((a < d ? a++ : a) = d)
which is a semantic error, since the result of the conditional-expression (which might be a++) is not an lvalue. In C++, it is parsed as:
e = (a < d ? a++ : (a = d))
which is a valid expression.
Please someone explain the bold text in the above quotation! Pleas开发者_JAVA百科e explain the grammar with few more examples (especially those where C and C++ differ).
EDIT : I just want to know how to read and understand them. I mean, if I were to explain that in spoken English, then how would I do that?
Here's a description of the C++ grammar for expressions, which defines assignment-expression as
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
In plain English, an assignment-expression can be either a conditional-expression OR a unary-expression, followed by an assignment-operator, followed by an assignment-expression. So, your next question is 'what's a conditional expression' and you consult that part of the grammar, and keep going until you reach the bottom!
So in C++ you can see the operator you referred to can take a 'conditional-expression' as in C, but also an assignment
So with your 'C' hat on, you look at the final a = d
part of the operator as an assignment, which the C syntax shouldn't allow. Instead, it would seem some compilers parse the final part of the operator simple as a
to to give
e = (a < d ? a++ : a) = d
But in C++, it's valid to find an assignment there, so the a = d
is accepted in its entirety as the final expression, so you get
e = (a < d ? a++ : (a = d))
You have to refer to what an assignment-expression is. It is defined in the C++03 standard in 5.17/1 [expr.ass] :
assignment-expression:
conditional-expression
logical-or-expression assignment-operator assignment-expression
throw-expression
assignment-operator: one of
= *= /= %= += -= >>= <<= &= ˆ= |=
What it says is that an assignment-expression can be either :
- A conditional-expression
- A logical-or-expression followed by an assignment-operator followed by an assignment-expression
- A throw-expression.
I'm not quoting the grammar definition of everything because that would be pretty huge (most notably because condition-expression covers a lot of things).
So the first thing we see is that an assignment-expression can be a conditional-expression, so we have the C syntax covered. What the C++ standard adds is that the right side of the :
can also be something containing an assignment-operator or a throw.
The provided example is good : e = a < d ? a++ : a = d
.
Here, the right side of the :
is a logical-or-expression (a
, because unary-expression is included in logical-or-expression), followed by an assignment-operator (=
), followed by an assignment-expression (d
, because unary-expression is included in assignment-expression).
Basically, things like:
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
(as mentioned in some other answers here) are rules used for describing the "grammar" of valid C (or C++). These written-down rules adhere to a certain grammar, too — so I would suggest that you learn that grammar, so that you'll be able to read and understand the rules.
For a start, you could study e.g. the Backus-Naur Form, if you don't already know it. (My link goes to the Wikipedia article on this topic.) While the C++ standard doesn't use Backus-Naur form (IIRC), it's similar enough to get you started.
精彩评论