C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] labels

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Thu, 13 Aug 2020 09:55:50 +0200
On 13/08/2020 09.07, Uecker, Martin wrote:
>
>
> Am Mittwoch, den 12.08.2020, 23:49 +0200 schrieb Jens Maurer:
>> On 12/08/2020 20.34, Uecker, Martin wrote:
>>> Am Mittwoch, den 12.08.2020, 09:26 -0700 schrieb Richard Smith:
>>>> On Wed, 12 Aug 2020, 04:26 Uecker, Martin via Liaison, <
>>>> liaison_at_[hidden]> wrote:
>>>>
>>>>> Am Dienstag, den 11.08.2020, 17:29 +0200 schrieb Jens Maurer:
>>>>>> On 11/08/2020 08.37, Uecker, Martin via Liaison wrote:
>>>>>>> Hi all,
>>>>>>>
>>>>>>> I recently proposed changes to the C grammar which got
>>>>>>> voted into C2X by WG14 (N2508, also see N2496).
>>>>>>>
>>>>>>> This allows placing of labels everywhere in a compound
>>>>>>> statement, even before declarations and at the end
>>>>>>> of a block, which was not possible in C so far.
>>>>>>>
>>>>>>> Example:
>>>>>>>
>>>>>>> {
>>>>>>> start:
>>>>>>> int i;
>>>>>>> mid:
>>>>>>> int j;
>>>>>>> end:
>>>>>>> }
>>>>>>>
>>>>>>> It has been pointed out to me that while C++ allows
>>>>>>> labels before declarations, it does not allow them
>>>>>>> at the end of a compound statement.
>>>>>>>
>>>>>>> I plan to propose a change to C++ to make this
>>>>>>> possible too and I wonder if you have any comments
>>>>>>> or suggestions related to this?
>>>>>>
>>>>>> I'm lukewarm on this. Your example becomes valid C++
>>>>>> by adding a ";" after the "end:".
>>>>>>
>>>>>> So, having the change does not materially alter the
>>>>>> expressiveness of the common subset of C++ and C.
>>>>>
>>>>> It would enhance compatibility.
>>>>>
>>>>>> I'd like to see the wording change for C++ to understand
>>>>>> whether it's likely low-cost overall to add this.
>>>>>
>>>>> Ok, no wording yet, but the suggested grammar change would
>>>>> be as follows (omitting attributes for simplicity):
>>>>>
>>>>> 8.1(1) gets refactored from
>>>>>
>>>>> statement:
>>>>> labeled-statement
>>>>> expression-statement
>>>>> compound-statement
>>>>> selection-statement
>>>>> iteration-statement
>>>>> jump-statement
>>>>> declaration-statement
>>>>> try-block
>>>>>
>>>>> to the following:
>>>>>
>>>>> statement:
>>>>> labeled-statement
>>>>> unlabeled-statement
>>>>> declaration-statement
>>>>>
>>>>
>>>> The separation of declaration-statement here seems arbitrary (and
>>>> incorrect
>>>> without changes elsewhere, since we specify execution semantics
>>>> for
>>>> declaration-statements that don't apply to declarations in
>>>> general, in
>>>> particular registering atexit destructors for static locals).
>>
>> Agreed. It also seems easier to me to simply introduce an optional
>> sequence of labels at the end of a compound-statement, instead of
>> a large-ish refactoring of the C++ grammar.
>
> I would not call it large. It would be two additional
> minor self-contained changes to create explicit
> productions for "label" and "unlabeled-statements".

Plus a change in the definition of "compound-statement".

> I see several advantages of the changes above over
> adding something special just for labels at the end of
> the block:
>
> - more similar structure to the C grammar

I don't see this as a goal per se. The grammar is a
means to an end, and C++ and C are sufficiently different
that they may reasonable choose different grammar
representations.

For example, if we do go the "unlabeled-statement" route,
I'd still ask for "declaration-statement" to be part of
"unlabeled-statement" for C++, instead of being separate
inside compound-statement. Traditionally, a declaration
has been "just another statement" in C++, even if that has
possibly non-sensical fall-out in a few corner cases.

Trying to make something like

  if (blah)
     int y;

ill-formed in C++ is a much larger change than the question
of labels.

> - more symmetry: all labels inside compound statements
> are treated equally, which makes a lot of sense to me.
> Fundamentally, there is no difference and I think it
> is good when the grammar reflects this.

But labels on single (non-compound) statements appear to
be treated differently with this change; that's the flip
side of the coin.

> - Finally, with the production at the end of the
> compound struct, the parser may occasionally
> need to to backtrack out of a series of labels.

The grammar as specified in the standard may be different
from what any specific parser actually implements. For
example, the -list and -seq constructs are presented in a
left-recursive manner for C++, but I thought I'd heard some
implementations prefer to parse them the other way round.

I also note that [stmt.select] p2 in C++ has a rewrite
rule that says we're rewriting a single-substatement of
an "if" as a compound-statement. With your proposed grammar
change, we're not just moving a "statement" inside a
"compound-statement", but we have to (notionally) re-parse
this, because any labels now match different grammar
productions.

>> In C++, we say in [stmt.goto]
>> "The goto statement unconditionally transfers control to the
>> statement labeled by the identifier."
>>
>> This is obviously not true for labels at the end of a compound-
>> statement,
>> because there is no statement that is labeled in that case.
>>
>> So, we need a wording change here.
>
> Yes, this is clear. We have wording to always
> add an implied null statement to labels inside compound
> statements.

Great.

Jens

Received on 2020-08-13 02:59:17