Version 1.5 of ai05s/ai05-0179-1.txt

Unformatted version of ai05s/ai05-0179-1.txt version 1.5
Other versions for file ai05s/ai05-0179-1.txt

!standard 5.1(2)          10-04-05 AI05-0179-1/04
!class Amendment 09-10-29
!status Amendment 2012 10-04-05
!status ARG Approved 10-0-0 10-02-26
!status work item 09-10-29
!status received 09-10-29
!status received
!priority Low
!difficulty Easy
!subject Labels at end of a sequence_of_statements
!summary
A label is allowed at the end of a sequence_of_statements.
!problem
One of the most common uses of gotos in Ada is to "continue" a loop. That is, complete the current iteration and go on to the next one. Nearly 25% of the gotos in the GNAT compiler are for this purpose.
This looks something like:
loop ... goto Continue; -- Usually deeply nested. ... <<Continue>> null; end loop;
The "null;" here is just noise. We're going to the end of the construct. But we need the "null;" since a label is not allowed at the end of a sequence_of_statements.
Intuitively, a label marks a "place" in a sequence of statements; it doesn't mark a particular statement. When you "goto" to a label, you start executing at that place and continue on with all the rest of the statements. Therefore, it makes perfect sense to have a label after the last statement in a sequence; the "null;" adds no benefit at all; it should be eliminated (especially as a large percentage of uses of labels are currently saddled with this noise).
!proposal
(See summary.)
!wording
Modify 5.1(2) to:
sequence_of_statements ::= statement {statement} {label}
Add after 5.1(12): (Static semantics)
If one or more labels end a sequence_of_statements, an implicit null_statement follows the labels before any following constructs.
!discussion
It is odd indeed that a label can start a sequence of statements, but it cannot end a sequence of statements. There is no practical difference in readability.
We define such a label as being followed by an implicit null_statement so that the formal semantics of a goto_statement is preserved (which transfers control to a statement, not to the label itself). Changing that semantics to something more consistent with the intuitive model mentioned in the !problem was considered, but seemed to have much more wording change than required for such a simple change to the language.
We retain the requirement that a sequence of statements include at least one statement (a label all by itself is still not allowed). So the following is allowed by this proposal:
if A then null; <<Lab>> end if;
But the following is still illegal:
if A then <<Lab>> -- Illegal end if;
And the following is still legal (of course):
if A then <<Lab>> null; end if;
!example
loop
... goto Continue; -- Usually deeply nested. ... <<Continue>>
end loop;
!corrigendum 5.1(2)
Replace the paragraph:
sequence_of_statements ::= statement {statement}
by:
sequence_of_statements ::= statement {statement} {label}
!corrigendum 5.1(12)
Insert after the paragraph:
For each statement_identifier, there is an implicit declaration (with the specified identifier) at the end of the declarative_part of the innermost block_statement or body that encloses the statement_identifier. The implicit declarations occur in the same order as the statement_identifiers occur in the source text. If a usage name denotes such an implicit declaration, the entity it denotes is the label, loop_statement, or block_statement with the given statement_identifier.
the new paragraph:
If one or more labels end a sequence_of_statements, an implicit null_statement follows the labels before any following constructs.
!ACATS test
Update the existing ACATS B-Test to test the syntax changes.
!appendix

From: Robert Dewar
Sent: Saturday, October 17, 2009  4:25 AM

[Editor's note: forked from the thread in AI05-0180-1.]

> The only reason to have a feature is to help out the "goto-adverse",
> and using the keyword "goto" isn't going to make them very happy.

Right, also the requirement for null after the Continue label is an irritation,
perhaps we could at least remove that entirely useless requirement, and allow a
label to appear on an end line.

****************************************************************

From: Bob Duff
Sent: Saturday, October 17, 2009  12:13 PM

> > The only reason to have a feature is to help out the "goto-adverse",
> > and using the keyword "goto" isn't going to make them very happy.
>
> Right, also the requirement for null after the Continue label is an
> irritation, perhaps we could at least remove that entirely useless
> requirement, and allow a label to appear on an end line.

OK, after all my recent negativity, I'll say something positive.  ;-)

I support the idea of changing the syntax as Robert suggests.  It's a trivial
change to implementations.  Intuitively, a label marks a "place" in a sequence
of statements.  It doesn't mark a particular statement.  If you "goto" that
place, you don't just execute the one labeled statement as the current syntax
would imply -- you start executing there and continue on with all the rest of
the statements.  Therefore, it makes perfect sense to have a label after the
last statement in a sequence; the "null;" is just noise.

For that matter, I'd allow:

    procedure P (...) is
    begin
        -- Nothing to do.
    end P;

and:

    procedure P (...) is
    begin
        pragma Assert (...);
    end P;

But those may be controversial.  Surely the label case is not controversial.

****************************************************************

From: Bob Duff
Sent: Sunday, October 18, 2009  1:11 PM

>  >> I must say I am surprised by Erhard saying he has  >> never felt a
> need for this, I find it pretty  >> common, and a grep for "goto
> Continue" in the  >> GNAT sources gets 65 hits.

Probably Erhard meant that he doesn't need a new feature for this, since often
an 'if' works fine, and when it doesn't, an 'if...goto' works just fine.

>  > That's 65 cases in 1,041,737 lines of code.
>  > 65/1,041,737 = 0.00006, which I wouldn't call  > "pretty common".
>
> What is that as a percentage of all the uses of 'goto' in the GNAT
> sources?

I count 522 goto statements.  (A bit surprising -- I would have guessed 100 or
so.)  72 of these are "goto Continue;" (not sure why Robert got 65), but there
are other labels that look like the programmer was thinking "continue":

goto Cont;
goto Cont1;
goto Cont2;
goto Continue;
goto Continue_Main_Component_Loop;
goto Line_Loop_Continue;
goto Loop_Continue;
goto Ploop_Continue;
goto Rloop_Continue;

The above account for 118 goto statements.

522/1,041,737 = 0.0005

118/522 = 0.23

****************************************************************

From: Bob Duff
Sent: Friday, Fberuary 26, 2010  2:49 PM

Proposed change in end of the discussion:

We retain the requirement that a sequence of statements include at least one
statement (a label all by itself is still not allowed). So the following is
allowed by this proposal:

   if A then
      null; <<Lab>>
   end if;

As before, the following is still illegal:

   if A then
      <<Lab>> -- Illegal
   end if;

And the following is still legal:

   if A then
      <<Lab>> null;
   end if;

****************************************************************

Questions? Ask the ACAA Technical Agent