17
votes

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! Please 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?

3
The ISO standards use EBNF for their grammar descriptions. Do you understand how to read this? If so the grammar rules should be pretty clear. en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_FormCB Bailey
Are you sure you mean "terrific experience" (wonderful) and not "terrifying experience" (horrible)? :)fredoverflow
There are good reasons that such standards are not written in 'plain English'; not the least of these is that 'plain English' is generally ambiguous and the standards are intended to be unambiguous. These standards are not intended to provide a source of learning material for beginners, but a reference for compiler-writers (and allied trades).High Performance Mark
@Nawaz: that third meaning is archaic -- no one uses it that way anymore. "Terrifying" (or perhaps "terrible") are the words you want.wnoise
upvoted for the sincere learning attempthAcKnRoCk

3 Answers

6
votes

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))
6
votes

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).

1
votes

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.