Topic: Probable defect: 'for' loop equivalent


Author: James Kuyper <jameskuyper@verizon.net>
Date: Sat, 3 Jan 2009 03:10:55 CST
Raw View
Greg Herlihy wrote:
>
> On Jan 1, 1:04 am, James Kuyper <jameskuy...@verizon.net> wrote:
>>
>> 6.5p2 provides those braces:
>> | If the substatement in an iteration-statement is a single statement
>> | and not a compound-statement, it is as if it was rewritten to be a
>> | compound-statement containing the original statement. [ Example:
>> |
>> |   while (--x >= 0)
>> |     int i;
>> |
>> | can be equivalently rewritten as
>> |   while (--x >= 0) {
>> |     int i;
>> |   }
>>
>> Thus
>>
>>   for( ;; x = 666 ) int x;
>>
>> behaves the same as if it were rewritten as
>>
>>   for( ;; x = 666 ) {int x;}
>>
>> The corresponding while statement is therefore
>>
>>    while()
>>    {
>>        { int x; }
>>        x = 666;
>>    }
>
> But if the original for-loop is transformed into the equivalent while-
> loop -without first converting a (non-compound) "statement" into a
> compound statement - then Alf is correct: "expression" will be inside
> "statement"'s scope.  ...

But 6.5p2 requires that such a conversion occurs.

> ... So the Standard is really stating that whether
> "expression" falls inside "statement"'s scope or not - should make no
> difference here. ...

It's not saying that it makes no difference, it's saying that the
difference it makes MUST occur.

> ... And on this point, the Standard is (almost) right.

The standard can't be "wrong"; it defines what "right" means in this
context. It might be defective - it might be internally inconsistent,
or it might not express what the committee intended it to express, but
whatever it is that it does express is what is "right".

> The problem with the while-loop transformation - as it turns out - is
> not the one originally cited: In other words there is no possibility
> that "expression" will be able to refer to declarations in "statement"
> deliberately. After all, in the original "for" construct, "expression"
> was definitely not in the same scope as "statement",

The standard's says nothing specifically about scope as it applies to
for() statements (or while() statements, for that matter). What the
standard says about scope can be applied to while() statements only
after they've been transformed in accordance with 6.5.1p2, at which
point it becomes clear that the declaration of 't' is in scope within
the sub-statement, while any declaration that occurs within the
sub-statement has scope only within that sub-statement. Similarly,
what the standard says about scope can only be applied to a for()
statement after it's been transformed in accordance with 6.5.3p1.

If you ignore 6.5p2, and apply only 6.5.3p1, then the expression does
occur within the scope of any identifiers declared in a sub-statement
that is a single declaration-statement.

> For example, according to the current C++ Standard, the for-loop that
> appears in the code below:
>
>   int j;
>
>   for ( int i = 0; i < 5; j++, i++)
>       double j = 4.0;
>
> can be transformed into a while-loop like so:
>
>   int j = 0;
>
>   int i = 0;
>
>   while ( i < 5 )
>   {
>       double j = 4.0;
>
>       j++, i++;
>   }
>
> with no effect on the program. Yet the while loop in this example is
> not equivalent to the original for-loop (the value of the int "j" is
> incremented in the for-loop, but remains unchanged in the while loop)

The meaning of the for() loop is DEFINED to be equivalent to the
corresponding while(), so it's meaningless to say that they are not
equivalent. You may say that there's a defect in that equivalence
which produces unexpected results, or expresses incorrectly the
intended equivalence, but you can't say that they inequivalent.

6.5p2 applies to all iteration statements, not just while()
statements. It's a more general rule, and therefore takes precedence
over the more specific rule; I believe that this means that it must be
applied before applying 6.5.3p1.

> So I would now agree with the original posting that the "for-loop" to
> "while-loop" equivalence described in the current C++ Standard is not
> correct in all cases; though I would differ on the explanation why.

I think it would be clearer to at least cross-reference 6.5p2 inside
of 6.5.3, preferably with a comment that it applies before that
transformation, not afterward.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: alfps <alf.p.steinbach@gmail.com>
Date: Tue, 30 Dec 2008 18:47:55 CST
Raw View
Paragraph    6.5.3/1 informs us that the 'for' statement

   for ( for-init-statement condition[opt] ; expression[opt] )
statement

is equivalent to

   {
       for-init-statement
       while ( condition ) {
       statement
       expression ;
       }
   }

This allows the 'expression' to refer to a variable declared in
'statement', e.g.

   for( ;; x = 666 ) int x;

As far as I know no C++ compiler conforms to the standard in this
respect, so perhaps it should be fixed?

A little pair of braces around 'statement' in the equivalence code
should suffice.


Cheers & hth.,

- Alf


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@mac.com>
Date: Tue, 30 Dec 2008 23:12:42 CST
Raw View
On Dec 30, 7:47 pm, alfps <alf.p.steinb...@gmail.com> wrote:
> Paragraph 6.5.3/1 informs us that the 'for' statement
>
>    for ( for-init-statement condition[opt] ; expression[opt] )
> statement
>
> is equivalent to
>
>    {
>        for-init-statement
>        while ( condition ) {
>        statement
>        expression ;
>        }
>    }

I don't see a problem here.    6.5.3 describes the behavior of a
(syntactically valid) "for" loop. So, the "for" loop must be
gramatically correct before an equivalent while loop can be
constructed.

Moreover, the transformation described is strictly one-way: that is,
although every "for" loop can be expressed as a while loop - there is
no inverse guarantee: that every while loop can be transformed into an
equivalent "for" loop - as your example suggests..

> This allows the 'expression' to refer to a variable declared in
> 'statement', e.g.
>
>    for( ;; x = 666 ) int x;

The above "for" statement is ill-formed syntactically, so its behavior
is equivalent to nothing.

Greg


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "jdennett@acm.org" <james.dennett@gmail.com>
Date: Wed, 31 Dec 2008 13:08:35 CST
Raw View
On Dec 30, 9:12 pm, Greg Herlihy <gre...@mac.com> wrote:
> On Dec 30, 7:47 pm, alfps <alf.p.steinb...@gmail.com> wrote:
>
> > Paragraph 6.5.3/1 informs us that the 'for' statement
>
> >    for ( for-init-statement condition[opt] ; expression[opt] )
> > statement
>
> > is equivalent to
>
> >    {
> >        for-init-statement
> >        while ( condition ) {
> >        statement
> >        expression ;
> >        }
> >    }
>
> I don't see a problem here. 6.5.3 describes the behavior of a
> (syntactically valid) "for" loop.

How do you deduce this?  I see nothing in 6.5.3 restricting the
equivalence to for loops that are "valid" in any sense -- 6.5.3
defines valid for statements, and does so by saying that they are
valid exactly when a given construct (using a while statement) is
valid, and have the same behavior except for the exceptions noted.

> So, the "for" loop must be
> gramatically correct before an equivalent while loop can be
> constructed.

I'd have to see a justification for that claim.

> Moreover, the transformation described is strictly one-way: that is,
> although every "for" loop can be expressed as a while loop - there is
> no inverse guarantee: that every while loop can be transformed into an
> equivalent "for" loop - as your example suggests..

Nothing says that it's one-way, so far as I see, and generally a
statement that "A is equivalent to B" is symmetric, having the same
meaning as "B is equivalent to A".

> > This allows the 'expression' to refer to a variable declared in
> > 'statement', e.g.
>
> >    for( ;; x = 666 ) int x;
>
> The above "for" statement is ill-formed syntactically, so its behavior
> is equivalent to nothing.

That's what we'd _like_ the standard to say, and it's what all
compilers implement, and we don't want them to change -- but the
standard doesn't seem to say so.  6.5.3 defines what the syntax above
means, no?

-- James



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: James Kuyper <jameskuyper@verizon.net>
Date: Thu, 1 Jan 2009 03:04:42 CST
Raw View
alfps wrote:
>
> Paragraph    6.5.3/1 informs us that the 'for' statement
>
>   for ( for-init-statement condition[opt] ; expression[opt] )
> statement
>
> is equivalent to
>
>   {
>       for-init-statement
>       while ( condition ) {
>       statement
>       expression ;
>       }
>   }
>
> This allows the 'expression' to refer to a variable declared in
> 'statement', e.g.
>
>   for( ;; x = 666 ) int x;
>
> As far as I know no C++ compiler conforms to the standard in this
> respect, so perhaps it should be fixed?
>
> A little pair of braces around 'statement' in the equivalence code
> should suffice.

6.5p2 provides those braces:
| If the substatement in an iteration-statement is a single statement
| and not a compound-statement, it is as if it was rewritten to be a
| compound-statement containing the original statement. [ Example:
|
|   while (--x >= 0)
|     int i;
|
| can be equivalently rewritten as
|   while (--x >= 0) {
|     int i;
|   }

Thus

   for( ;; x = 666 ) int x;

behaves the same as if it were rewritten as

   for( ;; x = 666 ) {int x;}

The corresponding while statement is therefore

    while()
    {
        { int x; }
        x = 666;
    }

Which gives 'x' exactly the scope that we knew it should have.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: alfps <alf.p.steinbach@gmail.com>
Date: Thu, 1 Jan 2009 03:03:39 CST
Raw View
On 31 Des, 06:12, Greg Herlihy <gre...@mac.com> wrote:
> On Dec 30, 7:47 pm, alfps <alf.p.steinb...@gmail.com> wrote:
>
> > Paragraph 6.5.3/1 informs us that the 'for' statement
>
> >    for ( for-init-statement condition[opt] ; expression[opt] )
> > statement
>
> > is equivalent to
>
> >    {
> >        for-init-statement
> >        while ( condition ) {
> >        statement
> >        expression ;
> >        }
> >    }
>
> I don't see a problem here. 6.5.3 describes the behavior of a
> (syntactically valid) "for" loop. So, the "for" loop must be
> gramatically correct before an equivalent while loop can be
> constructed.

Noted and agreed, (A) you don't see a problem, and (B) completely
unrelated to the first but completely correct, the loop must be
syntactically correct.


> Moreover, the transformation described is strictly one-way: that is,
> although every "for" loop can be expressed as a while loop - there is
> no inverse guarantee: that every while loop can be transformed into an
> equivalent "for" loop - as your example suggests..

I'm sorry, but as a technical observation about the subject matter
your statement is completely meaningless to me.

First, the "direction" of the equivalence is a meaningless concept: an
equivalence does not have a direction, it's an equivalence. Second, my
example (below) didn't suggest anything like what you're stating: no
simple single line of code can suggest such a thing. Third, contrary
to what you write (i.e. you're wrong on the factual as well), every
while loop can trivially be expressed as a for loop, including the use
of a named loop condition.


> > This allows the 'expression' to refer to a variable declared in
> > 'statement', e.g.
>
> >    for( ;; x = 666 ) int x;
>
> The above "for" statement is ill-formed syntactically, so its behavior
> is equivalent to nothing.

I'm sorry, you're wrong again: the above for loop is syntactically
correct.

Consider the program

<code>
int main()
{
   for( ;; ) int x;

   int y;
   for( ;; y = 666 ) {}
}
</code>

If you're interested in identifying what you have misunderstood about
the syntax rules, please point out what you think is a syntax error in
this program, with reference to the C++ standard's BNF syntax rules.

Or, it may be the case that you're confusing syntax with semantics
(then being wrong about semantics rather than about syntax). But I
guess that if you simply try to describe what you think is a syntax
error, we'll sort that out.


Cheers & hth.,

- Alf


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: James Kuyper <jameskuyper@verizon.net>
Date: Thu, 1 Jan 2009 03:02:44 CST
Raw View
Greg Herlihy wrote:
>
> On Dec 30, 7:47 pm, alfps <alf.p.steinb...@gmail.com> wrote:
>>
>> Paragraph 6.5.3/1 informs us that the 'for' statement
>>
>>   for ( for-init-statement condition[opt] ; expression[opt] )
>> statement
>>
>> is equivalent to
>>
>>   {
>>       for-init-statement
>>       while ( condition ) {
>>       statement
>>       expression ;
>>       }
>>   }
>
> I don't see a problem here.    6.5.3 describes the behavior of a
> (syntactically valid) "for" loop. So, the "for" loop must be
> gramatically correct before an equivalent while loop can be
> constructed.
>
> Moreover, the transformation described is strictly one-way: that is,
> although every "for" loop can be expressed as a while loop - there is
> no inverse guarantee: that every while loop can be transformed into an
> equivalent "for" loop - as your example suggests..

I agree that there's no such guarantee, but he made no use of the
inverse transformation, and therefore did not rely upon that
non-existent guarantee.

>> This allows the 'expression' to refer to a variable declared in
>> 'statement', e.g.
>>
>>   for( ;; x = 666 ) int x;
>
> The above "for" statement is ill-formed syntactically, so its behavior
> is equivalent to nothing.

The problem is not syntax, it's semantics. "x = 666" occurs outside of
the scope of the declaration of 'x', but only because of 6.5p2, as I
explained in my direct response to Alf. If the only relevant clause
were 6.5.3p1, then there would have been no curly brackets putting
'x=666' outside of the scope of that declaration.

Did you think that 'int x;' was not permitted to be the entire
sub-statement of a for() statement? I thought so too, because I'm more
familiar with C than C++, but that's because C distinguishes between
statements and declarations. That distinction does not exist in C++; a
declaration-statement is one of the permitted forms of a statement
(6p1,  6.7).


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: alfps <alf.p.steinbach@gmail.com>
Date: Thu, 1 Jan 2009 16:42:17 CST
Raw View
On 1 Jan, 10:04, James Kuyper <jameskuy...@verizon.net> wrote:
>
> 6.5p2 provides those braces:

(This is    6.5/2 in C++0x, but    6.5/3 in the current C++98 standard.)


> | If the substatement in an iteration-statement is a single statement
> | and not a compound-statement, it is as if it was rewritten to be a
> | compound-statement containing the original statement. [ Example:
> |
> |   while (--x >= 0)
> |     int i;
> |
> | can be equivalently rewritten as
> |   while (--x >= 0) {
> |     int i;
> |   }
>
> Thus
>
>    for( ;; x = 666 ) int x;
>
> behaves the same as if it were rewritten as
>
>    for( ;; x = 666 ) {int x;}
>
> The corresponding while statement is therefore
>
>     while()
>     {
>         { int x; }
>         x = 666;
>     }
>
> Which gives 'x' exactly the scope that we knew it should have.

Thanks!

In view of the fact that neither I, James nor Greg caught that, i.e.
that the standard's lack of reference to that far away paragraph is a
bit confusing, I still think a fix of    6.5.3/1 would be good.

E.g. as just a mention of    6.5/3 (for C++0x, a mention of    6.5/2).

And/or as added curly braces in the 'for' loop equivalence code,
having those braces explicitly in the presented code rather than
having them implicitly there, to be added by the reader (I think the
latter, the current situation, is ungood, for who can guess that
braces have been *left out* of the code, to be added by the reader?).

Hopefully this can be done as just an editor change?


Cheers, & thanks,

- Alf


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@mac.com>
Date: Fri, 2 Jan 2009 02:40:39 CST
Raw View
On Jan 1, 1:02 am, James Kuyper <jameskuy...@verizon.net> wrote:
> Greg Herlihy wrote:
>
> > Moreover, the transformation described is strictly one-way: that is,
> > although every "for" loop can be expressed as a while loop - there is
> > no inverse guarantee: that every while loop can be transformed into an
> > equivalent "for" loop - as your example suggests..
>
> I agree that there's no such guarantee, but he made no use of the
> inverse transformation, and therefore did not rely upon that
> non-existent guarantee.

The goal here is to prove that the example "for-loop" is a valid C++
construct. So the supporting argument cannot be: "take an
ungrammatical for-loop, then..." because there is no way to show that
an ungrammatical for-loop is, in fact, grammatical. Similarly, an
argument cannot begin with "take a grammatical for-loop, then..."
because when starting with grammatical for-loop, nothing further needs
to be done to show that for-loop is, well, grammatical.

So the only way to arrive at the conclusion that the example for-loop
is a valid C++ construct is to start with something other than the for-
loop itself - in this case, the starting point is a grammatical while-
loop. And in fact, if C++ guaranteed a while-loop to for-loop
transformation, this argument would be perfectly valid and sound. But
in reality, the for-loop is grammatical only if it conforms to the C++
grammar defined by the C++ Standard.

> >> This allows the 'expression' to refer to a variable declared in
> >> 'statement', e.g.
>
> >>   for( ;; x = 666 ) int x;
>
> > The above "for" statement is ill-formed syntactically, so its behavior
> > is equivalent to nothing.
>
> The problem is not syntax, it's semantics. "x = 666" occurs outside of
> the scope of the declaration of 'x', but only because of 6.5p2, as I
> explained in my direct response to Alf. If the only relevant clause
> were 6.5.3p1, then there would have been no curly brackets putting
> 'x=666' outside of the scope of that declaration.

Yes, "syntactically" was the wrong word. I should have written
"grammatically ill-formed" And precisely for the reasons you cite:
grammatically, the for-loop's "statement" comes after its
"expression", so any declarations made in "statement" would not be
visible in the scope of "expression".

Greg



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@mac.com>
Date: Fri, 2 Jan 2009 04:17:17 CST
Raw View
On Jan 1, 1:04 am, James Kuyper <jameskuy...@verizon.net> wrote:
>
> 6.5p2 provides those braces:
> | If the substatement in an iteration-statement is a single statement
> | and not a compound-statement, it is as if it was rewritten to be a
> | compound-statement containing the original statement. [ Example:
> |
> |   while (--x >= 0)
> |     int i;
> |
> | can be equivalently rewritten as
> |   while (--x >= 0) {
> |     int i;
> |   }
>
> Thus
>
>    for( ;; x = 666 ) int x;
>
> behaves the same as if it were rewritten as
>
>    for( ;; x = 666 ) {int x;}
>
> The corresponding while statement is therefore
>
>     while()
>     {
>         { int x; }
>         x = 666;
>     }

But if the original for-loop is transformed into the equivalent while-
loop -without first converting a (non-compound) "statement" into a
compound statement - then Alf is correct: "expression" will be inside
"statement"'s scope. So the Standard is really stating that whether
"expression" falls inside "statement"'s scope or not - should make no
difference here. And on this point, the Standard is (almost) right.

The problem with the while-loop transformation - as it turns out - is
not the one originally cited: In other words there is no possibility
that "expression" will be able to refer to declarations in "statement"
deliberately. After all, in the original "for" construct, "expression"
was definitely not in the same scope as "statement", so nothing in
"expression" could refer to any declaration in "statement" in the
while loop, because no such reference could have existed before the
transformation to the while-loop ever took place..

In fact, the problem is not that "expression" intentionally refers to
a declaration in "statement" but instead, that "expression" does so,
inadvertently. That is, by placing "statement" and "expression" in the
same scope (when they were not in the same scope, originally), it is
possible to create unintentional references in "expression" to
declarations made in "statement".

For example, according to the current C++ Standard, the for-loop that
appears in the code below:

   int j;

   for ( int i = 0; i < 5; j++, i++)
       double j = 4.0;

can be transformed into a while-loop like so:

   int j = 0;

   int i = 0;

   while ( i < 5 )
   {
       double j = 4.0;

       j++, i++;
   }

with no effect on the program. Yet the while loop in this example is
not equivalent to the original for-loop (the value of the int "j" is
incremented in the for-loop, but remains unchanged in the while loop).

So I would now agree with the original posting that the "for-loop" to
"while-loop" equivalence described in the current C++ Standard is not
correct in all cases; though I would differ on the explanation why.

Greg


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "jdennett@acm.org" <james.dennett@gmail.com>
Date: Fri, 2 Jan 2009 09:46:35 CST
Raw View
On Jan 2, 12:40 am, Greg Herlihy <gre...@mac.com> wrote:
> On Jan 1, 1:02 am, James Kuyper <jameskuy...@verizon.net> wrote:
>
> > Greg Herlihy wrote:
>
> > > Moreover, the transformation described is strictly one-way: that is,
> > > although every "for" loop can be expressed as a while loop - there is
> > > no inverse guarantee: that every while loop can be transformed into an
> > > equivalent "for" loop - as your example suggests..
>
> > I agree that there's no such guarantee, but he made no use of the
> > inverse transformation, and therefore did not rely upon that
> > non-existent guarantee.
>
> The goal here is to prove that the example "for-loop" is a valid C++
> construct.

So far, so good.

> So the supporting argument cannot be: "take an
> ungrammatical for-loop, then..." because there is no way to show that
> an ungrammatical for-loop is, in fact, grammatical. Similarly, an
> argument cannot begin with "take a grammatical for-loop, then..."
> because when starting with grammatical for-loop, nothing further needs
> to be done to show that for-loop is, well, grammatical.

Indeed.  Instead, we start with an example for loop, and attempt to
determine whether it is correct, without making assumptions.

> So the only way to arrive at the conclusion that the example for-loop
> is a valid C++ construct is to start with something other than the for-
> loop itself

False.  Starting with the for loop is the obvious (and correct) way to
proceed.  The standard _defines_ the for loop in terms of a
transformation to a while loop.  If you have something that is
syntactically of the form of a for loop, and is valid when correctly
transformed, then it is correct.

(The tricky part is that the transformation is in two stages, first
making the body of the for loop a compound statement, and then
converting to a while loop, and that there are some exceptions noted
also.)

>- in this case, the starting point is a grammatical while-
> loop. And in fact, if C++ guaranteed a while-loop to for-loop
> transformation, this argument would be perfectly valid and sound. But
> in reality, the for-loop is grammatical only if it conforms to the C++
> grammar defined by the C++ Standard.

It does conform to the syntax, and except for the conversion to a
compound statement would conform to the semantic requirements as well:
the transformation to the while form *defines* the relevant scopes.

[...]
>
> > The problem is not syntax, it's semantics. "x = 666" occurs outside of
> > the scope of the declaration of 'x', but only because of 6.5p2, as I
> > explained in my direct response to Alf. If the only relevant clause
> > were 6.5.3p1, then there would have been no curly brackets putting
> > 'x=666' outside of the scope of that declaration.
>
> Yes, "syntactically" was the wrong word. I should have written
> "grammatically ill-formed" And precisely for the reasons you cite:
> grammatically, the for-loop's "statement" comes after its
> "expression", so any declarations made in "statement" would not be
> visible in the scope of "expression".

No, because the standard explicitly states that the "for" *is*
equivalent to the given "while".  You're assuming that a for loop has
semantics (including scoping) that somehow exist separately from its
definition in terms of while, and that's not the case.

However, this is all academic at this point, except for a possible
editorial improvement to add braces to the transformed version.

-- James



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: James Kuyper <jameskuyper@verizon.net>
Date: Fri, 2 Jan 2009 21:48:52 CST
Raw View
Greg Herlihy wrote:
>
> On Jan 1, 1:02 am, James Kuyper <jameskuy...@verizon.net> wrote:
>>
>> Greg Herlihy wrote:
>>
>>> Moreover, the transformation described is strictly one-way: that is,
>>> although every "for" loop can be expressed as a while loop - there is
>>> no inverse guarantee: that every while loop can be transformed into an
>>> equivalent "for" loop - as your example suggests..
>>
>> I agree that there's no such guarantee, but he made no use of the
>> inverse transformation, and therefore did not rely upon that
>> non-existent guarantee.
>
> The goal here is to prove that the example "for-loop" is a valid C++
> construct. So the supporting argument cannot be: "take an
> ungrammatical for-loop, then..."

I've denied that it's ungrammatical, for reasons already given. It
does have a problem, but that problem is that the expression is
outside of the scope of the declaration that it was apparently
intended to be inside. If there's no declaration of x outside the
loop, it's an attempt to use an identifier with no declaration of that
identifier in scope; if there is such a declaration, it's a use of a
different declaration than the one that was actually intended. Either
way, that's an matter of semantics, not grammar.

> So the only way to arrive at the conclusion that the example for-loop
> is a valid C++ construct is to start with something other than the for-
> loop itself - in this case, the starting point is a grammatical while-
> loop.

No, the argument for the validity of the for-loop as a C++ construct
was based upon not realizing the relevance of 6.5p2. It is a
grammatically correct for-statement which, if it weren't for 6.5p2,
would also have weird but valid semantics.

>>>> This allows the 'expression' to refer to a variable declared in
>>>> 'statement', e.g.
>>>>  for( ;; x = 666 ) int x;
>>>
>>> The above "for" statement is ill-formed syntactically, so its behavior
>>> is equivalent to nothing.
>>
>> The problem is not syntax, it's semantics. "x = 666" occurs outside of
>> the scope of the declaration of 'x', but only because of 6.5p2, as I
>> explained in my direct response to Alf. If the only relevant clause
>> were 6.5.3p1, then there would have been no curly brackets putting
>> 'x=666' outside of the scope of that declaration.
>
> Yes, "syntactically" was the wrong word. I should have written
> "grammatically ill-formed" And precisely for the reasons you cite:
> grammatically, the for-loop's "statement" comes after its
> "expression", so any declarations made in "statement" would not be
> visible in the scope of "expression".

The only relevant grammar rules are those that say that an expression
and a statement are both allowed, in those portions of a for()
statement. The only statement we have about what a for() statement
means describes it's meaning in terms of an equivalent while()
statement. If it weren't for th 6.5p2; if 6.5.3p1 were the only
relevant clause, then that equivalent while() loop would put the
expression within the scope of the variable declared in that
statement.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]