Topic: ANSI for loop change?


Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 27 Mar 1995 13:35:16 GMT
Raw View
In article <bill_law-2003951113050001@bill-law.taligent.com>
bill_law@taligent.com (William A. Law) writes:

|> In article <D5LJ8C.7uA@ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max
|> Skaller) wrote:
|> >
|> >         Gak! Sorry. Old habits die hard. I didn't mean to decare
|> > i in the loop :-(

|> and, ironically...

|> In article <3k4i1p$chj@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve
|> Clamage) wrote:

|> >     for( int i=0; i < size && t1[i]==t2[i]; ++i )
|> >        ;
|> >     if( i == size ) return 0;

|> I guess Mr. Clamage didn't mean to reference i outside the loop.  It would
|> appear that this particular "enhancement" to C++ is going to be lots of
|> fun.

Just don't forget to declare a global int i in a header file
somewhere, to shut up the compiler:-).
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung






Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Fri, 17 Mar 1995 17:57:47 GMT
Raw View
In article <1995Mar13.091214.25258@siemens.co.at>,
Harald M. Mueller <mueller@garwein.hai.siemens.co.at> wrote:
>In article Kz1@ucc.su.OZ.AU, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>...
>|>It also extends naturally to:
>|>
>|> {
>|>  int i;
>|>  for(int i=0; i<n; ++i)
>|>  {
>|>   if(x[i])break;
>|>  }
>|>  if(i==n) { droped through }
>|>  else { found it }
>|>  // in all cases
>|> }
>
>Did I get this right???:
>You define an int i *before* the loop *and* *in* the loop, and then you
>dare to access the ("more global") i after the loop!!! Your beautiful
>code, if I'm at all correct, will always "find" at a undefined location!

 Gak! Sorry. Old habits die hard. I didn't mean to decare
i in the loop :-(

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: bill_law@taligent.com (William A. Law)
Date: Mon, 20 Mar 1995 19:12:34 GMT
Raw View
In article <D5LJ8C.7uA@ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max
Skaller) wrote:
>
>         Gak! Sorry. Old habits die hard. I didn't mean to decare
> i in the loop :-(

and, ironically...

In article <3k4i1p$chj@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve
Clamage) wrote:

>     for( int i=0; i < size && t1[i]==t2[i]; ++i )
>        ;
>     if( i == size ) return 0;

I guess Mr. Clamage didn't mean to reference i outside the loop.  It would
appear that this particular "enhancement" to C++ is going to be lots of
fun.

Bill Law




Author: mueller@garwein.hai.siemens.co.at (Harald M. Mueller)
Date: Mon, 13 Mar 1995 09:12:14 GMT
Raw View
In article Kz1@ucc.su.OZ.AU, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
...
|>It also extends naturally to:
|>
|> {
|>  int i;
|>  for(int i=0; i<n; ++i)
|>  {
|>   if(x[i])break;
|>  }
|>  if(i==n) { droped through }
|>  else { found it }
|>  // in all cases
|> }

Did I get this right???:
You define an int i *before* the loop *and* *in* the loop, and then you
dare to access the ("more global") i after the loop!!! Your beautiful
code, if I'm at all correct, will always "find" at a undefined location!

As I previously wrote, I do hestitatingly accept the change; however,
the mistake in the code above IMO shows that the change will be a hard
thing - even its proponents will either need a good compiler or a good
debugger or both to help them with the transition ...

Moreover, I again state the more fundamental problem with the change:
With the earlier definition, it is (was) *not* necessary to define
an empty constructor and an assignment operator for the iterator in
the for loop:

 class MyIterator {
     public: MyIterator(Set<Type>);
   bool valid();
   void operator++();
   Type& access();
 };

is enough to write

 for (MyIterator it = some_set; it.valid(); ++it) {
     ...use it.access()...
     if (...) break;
 }
 if (it.valid()) { /* break was executed, "found"  */ }
 else  { /* no break was executed, "not found" */ }

Under the new definition, we have to change this to:

 class MyIterator {
     public: MyIterator();
   void operator=(Set<Type>);
   bool valid();
   void operator++();
   Type& access();
 };

to write code like

 MyIterator it;
 for (it = some_set; it.valid(); ++it) {
     ...use it.access()...
     if (...) break;
 }
 if (it.valid()) { /* break was executed, "found"  */ }
 else  { /* no break was executed, "not found" */ }

the consequence of which is that we now have the concept of an "unitialized
iterator" (between the declaration and the for loop!), which is solely imposed
on us by the language (and if you try to define "safe iterators", you will
quickly find that you never do want such unitialized beasts!).

Of course, you *can* keep the previous definition of MyIterator by writing

 MyIterator it = some_set;
 for (; it.valid(); ++it) {
     ...use it.access()...
     if (...) break;
 }
 if (it.valid()) { /* break was executed, "found"  */ }
 else  { /* no break was executed, "not found" */ }

which is always correct (under the new and the old interpretation of
declarations in for loops), but then the "init_statement" part of the
for loop starts to become pretty useless.

Nevertheless, I'm still in favor of the change - only it *will* be a
hard time for those who used more sophisticated iterators than simple
ints.

HMMueller

== --------------------------------------------------------------
== Dr. Harald M. Mueller mueller@garwein.hai.siemens.co.at
== Siemens AG Austria  Siemens AG Austria
== PSE EZE TNA1   Erdberger Laende 26
== fax: +43-1-71711-5425 A-1030 Vienna/Austria
== --------------------------------------------------------------







Author: mueller@garwein.hai.siemens.co.at (Harald M. Mueller)
Date: Wed, 8 Mar 1995 09:13:47 GMT
Raw View
[Sorry that I post this a second time, but I want it to be in the correct
thread; the previous subject was "Scope of variables declared in for-loop".]

To add another viewpoint to the debate about the loop-declaration scope
(although this debate has already found its way into C++Report; and it
seems that the committee has already settled on the issue ...):

IMHO, there is a good reason why the "new way" for declaring iterators
which are used outside the loop

   int i;
   for(i=0; i<n; i++) {
  ...
 }
   x[i] = 0;

is significantly worse than the current one

   for (int i=0; i<n; i++) {
  ...
 }
   x[i] = 0;

The reason is that in the former, it is necessary to construct a "dangling
iterator" for a short while and, even worse, makes it necessary
to provide a constructor which will construct such a dangling iterator.
In our project, we have lots of loops of the following kind:

 for (Iterator<XXX> i_x = a_set_of_XXX; i_x.valid(); ++i_x) {
     ...
     }
 if (i_x.valid()) {
     ...
     }

We cannot change this to

 Iterator<XXX> i_x;
 for (i_x = a_set_of_XXX; i_x.valid(); ++i_x) {
etc.

as neither a parameterless constructor nor an assignment are defined for
Iterator<XXX> (please no arguments that they should be defined ... some of
these iterators have very complicated internal machinery, as they are very
"safe" iterators; there is simply no [easy] semantics of assignment which
makes sense with these iterators, and we do not see any good reason why we
should define some artificial one [e.g. only the parameterless constructor
creates a "no-good"-iterator, which can then be assigned to? but then we
would have to have a run-time check in the assignment whether
the iterator assigned to is indeed the no-good one, which (a) takes time
(which is wasted if the program is correct) and (b) no-one wants to change
static checks to runtime checks, anyway]).

We could instead write

 Iterator<XXX> i_x = a_set_of_XXX;
 for (; i_x.valid(); ++i_x) {
etc.

and we could even define a macro for that:

 #define our_for(init,test,incr) init; for(;test;incr)

or something like that.

Should we? I, IMHO, find this approach ugly and "not in the spirit of C++"
(which, after all, initially came up with the possibility of declaring a loop
variable in the for statement).

On the other hand [yes, I'm split-brain here ...], I have wanted these
if-declarations for a long time; and the longer I look at them, the more
I find that it is *right* that their scope ends with the branch(es) of the
if. The "correction" of the for-statement is then a must ...

So we will rewrite all our loops to

 Iterator<XXX> i_x = a_set_of_XXX;
 for (; i_x.valid(); ++i_x) {

and make this a PATTERN - albeit an ugly one!

HMMueller


== --------------------------------------------------------------
== Dr. Harald M. Mueller mueller@garwein.hai.siemens.co.at
== Siemens AG Austria  Siemens AG Austria
== EZE 41   Erdberger Laende 26
== fax: +43-1-71711-5425 A-1030 Vienna/Austria
== --------------------------------------------------------------







Author: gratz@ite121.inf.tu-dresden.de (Achim Gratz)
Date: 8 Mar 1995 11:28:41 +0100
Raw View
>>>>> "David" == David Vandevoorde <vandevod@pleiades.cs.rpi.edu> writes:

[...]
    David> Although I agree with the "consistency" argument, the
    David> original poster's point remains valid (I think): I expect
    David> that there is a lot of code out there that relies on the
    David> extended scope of induction variables declared in the
    David> for-clause. For one, many must have (looking at my own code
    David> :) been frustrated at the "rubbish" you mention above and
    David> replaced it by:

    David>  for (int i = ...
    David>  for (i = ...

Whoever is writing such code get what she/he deserves.  Think about
what would happen if somone deletes the first loop in an attempt to
maintain the program.  So even with the old rule, what should have
been written is:

int i;

for (i = ...
for (i =

Needless to say this will work with either rule and shows the
intention ("I want to use i not only as the loop index but also in
some other way!") clearly.  The new rule will also allow the other way
("I want i only as the loop index!"), and I'm glad that this
particular mess has been fixed.

    David> Has there been any thought about keeping the "old" behavior
    David> as a default and allowing the "new" behavior with some
    David> specific notation?
[...]


Compiler vendors may decide to support some sort of backup for these
and other changes (as they already do with other "obsolete features").
Why clutter the standard with it?  A standard isn't a history book,
IMHO.


--
Achim Gratz
-+==##{([***Murphy is always right***])}##==+-
E-Mail: gratz@ite.inf.tu-dresden.de
Phone:  +49 351 4575 - 325




Author: jason@cygnus.com (Jason Merrill)
Date: 07 Mar 1995 17:52:33 GMT
Raw View
>>>>> John Max Skaller <maxtal@Physics.usyd.edu.au> writes:

>> That's not an anonymous function, that's progn.

>  "progn" ?

LISP-speak for "evaluate these statements, and return the value of the last
one".

Jason




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Mon, 6 Mar 1995 01:55:02 GMT
Raw View
In article <MATT.95Mar2224616@physics7.berkeley.edu>,
Matt Austern <matt@physics.berkeley.edu> wrote:
>>
>>  The proposal has passed, by the way.
>
>I'm glad to hear that---and more than a bit surprised, actually.  I
>didn't think that the committee would be willing to break existing
>code, even for the sake of changing an obviously broken feature.

 This is a common misconception -- especially inside
the committee itself. On some issues a lot of noise is made
about breaking code, while on other issues which cause wholesale
destruction of massive bodies of code, everyone agrees the change
is worth it.

 For example, having "new" throw an exception rather
than return a 0 pointer breaks a LOT of code. Permitting
const objects to be allocated in ROM breaks code that
uses cast-away-const instead of the newer mutable feature.

 And currently a hot issue is whether to break
some code and almost all binaries, by changing (or rather,
establishing) a template model in which templates are full
linkable entities.

 And then people worry about introducing a few keywords
which might break a couple of programs. Sigh.

>There's going to be some pain for a while while we fix our old code,
>but the new semantics of variables declared in for loops (and in if
>statements, for that matter) is clearly correct.  My only regret is
>that it hadn't always been defined this way.

 Yes. I believe _most_ programmers and implementors
are smart enough -- and foresighted enough -- to prefer the
ARM C++ language to be changed so the ISO C++ language
is _better_ even if that breaks code now.

 We're all sick of changes: we need to grin and bear it until
we have a Standard.
>
>For the last few months, I've been trying pretty hard to write code
>that's correct under both the old and the new rules; all that means,
>of course, is that if I have more than one for loop in a single
>function then I use a different iteration variable for each.

 I write:

 {for(int i=0; i<n; ++i)
 {
  body
 }}

It looks kind of weird, but it works the same under both
the new and old rules and preserves the _cut and paste_ assurance
of the new properly scoped rules -- which using distinct variables
does not. (I.e. this technique has correct localisation properties)

It also extends naturally to:

 {
  int i;
  for(int i=0; i<n; ++i)
  {
   if(x[i])break;
  }
  if(i==n) { droped through }
  else { found it }
  // in all cases
 }

Of course, what we _really_ need here is anonymous local
functions:

 int k = function() {
  int i;
  for(int i=0; i<n; ++i)
  {
   if(x[i])break;
  }
  if(i==n) { droped through }
  else { found it }
  // in all cases
  return i;
 }

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: jason@cygnus.com (Jason Merrill)
Date: 06 Mar 1995 08:07:44 GMT
Raw View
>>>>> John Max Skaller <maxtal@Physics.usyd.edu.au> writes:

> Of course, what we _really_ need here is anonymous local
> functions:

>  int k = function() {
>   int i;
>   for(int i=0; i<n; ++i)
>   {
>    if(x[i])break;
>   }
>   if(i==n) { droped through }
>   else { found it }
>   // in all cases
>   return i;
>  }

That's not an anonymous function, that's progn.  GNU C/C++ have that:

int k = ({ int i;
  for (i=0; i<n; ++i)
    {
      if (x[i]) break;
    }
  if (i==n) { /* dropped through */; }
  else { /* found it */; }
  // in all cases
  i;
});

Anyone want to suggest adding lambda expressions?

Jason




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Tue, 7 Mar 1995 15:09:39 GMT
Raw View
In article <JASON.95Mar6000744@phydeaux.cygnus.com>,
Jason Merrill <jason@cygnus.com> wrote:
>>>>>> John Max Skaller <maxtal@Physics.usyd.edu.au> writes:
>
>> Of course, what we _really_ need here is anonymous local
>> functions:
>
>>  int k = function() {
>>   int i;
>>   for(int i=0; i<n; ++i)
>>   {
>>    if(x[i])break;
>>   }
>>   if(i==n) { droped through }
>>   else { found it }
>>   // in all cases
>>   return i;
>>  }
>
>That's not an anonymous function, that's progn.

 "progn" ?

>GNU C/C++ have that:
>
>int k = ({ int i;
>  for (i=0; i<n; ++i)
>    {
>      if (x[i]) break;
>    }
>  if (i==n) { /* dropped through */; }
>  else { /* found it */; }
>  // in all cases
>  i;
>});
>
>Anyone want to suggest adding lambda expressions?

 Sure. :-)

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sat, 4 Mar 1995 17:56:21 GMT
Raw View
graham@scitec.demon.co.uk (Graham Coles) writes:

>I have read in a professional C++ magazine that ANSI were planning on
>changing the for loop variable scope so that the loop variable ceases
>to exist on exit ....

Actually it's ANSI/ISO.

>Are they mad ?

No.

>Perhaps someone from the standards committee would like to explain why
>they thought this was such a good idea (*please* do, I'd love to know why).
>
>What else can I say, "IF IT AIN'T BROKE, DON'T DAMN WELL FIX IT!!!"

The problem is that it WAS broke.

The standards committee recently decided to allow

 void foo(Base* p) {
  if (X* xp = dynamic_cast<X*>(p)) {
   foo(xp->x_member);
  } else if (Y* yp = dynamic_cast<Y*>(p)) {
   foo(yp->y_member);
  }
 }

For various reasons which will probably become apparent if you
think about it for a while, the scope of a variable introduced
in an `if' statement must not extend beyond the `if'.

Having one rule for `if' and `while' and a DIFFERENT rule for `for'
would be VERY confusing.  The committee decided that in this case it
was prepared to break existing code in order to make C++ a simpler
language.

(Note: I'm a member of the committee now, but I think this decision was
made before I joined.  My explanation of the motivation comes from what
I have heard second or third hand or guessed myself.)

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Fri, 3 Mar 1995 05:41:51 GMT
Raw View
In article <793836691snz@scitec.demon.co.uk>,
Graham Coles <graham@scitec.demon.co.uk> wrote:
>I have read in a professional C++ magazine that ANSI were planning on
>changing the for loop variable scope so that the loop variable ceases
>to exist on exit ....
>
>Are they mad ?

 If you are going to accuse a committee of madness, at least
accuse the right body.

 The original paper -- and subsequent proposal to change
the semantics -- were from Steve Rumbsy of the UK delegation to
the ISO/SC22 working group WG21. (Both USA and UK are participants,
their national bodies are ANSI and BSI respectively).

 So please refer to the ANSI/ISO committee.
(ANSI has a special role and deserves special mention)

 The proposal has passed, by the way.

>Have they not heard of the term 'upward compatibility' ??

 Have you not heard of the notion of correctness?
 What about consistency?

>When are they going to retract this suggestion ...

 If you do not like it, complain at the time of the
ANSI public review, or, if you prefer, directly to the
Head of the UK delegation -- Steve Rumbsy :-)

 The reason for the change is that in the case:

 for(int i=1; bool valid = true; i++) { if(i>10)valid=false; }

 if(valid) {}// ERROR
 if(i) {} // OK????

was thought to be highly inconsistent. If the condition
is restricted in scope to _inside_ the loop, the control
variable should be too. In particular, the following
rubbish is fixed:

 for(int i=....
 for(int i= ... // ERROR duplicate declaration of i

A loop is a block, and the control variable -- as in PASCAL --
should be nested in the block if declared in it.
--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: matt@physics7.berkeley.edu (Matt Austern)
Date: 03 Mar 1995 06:46:16 GMT
Raw View
In article <D4untt.E0H@ucc.su.OZ.AU> maxtal@Physics.usyd.edu.au (John Max Skaller) writes:

>  The original paper -- and subsequent proposal to change
> the semantics -- were from Steve Rumbsy of the UK delegation to
> the ISO/SC22 working group WG21. (Both USA and UK are participants,
> their national bodies are ANSI and BSI respectively).
>
>  So please refer to the ANSI/ISO committee.
> (ANSI has a special role and deserves special mention)
>
>  The proposal has passed, by the way.

I'm glad to hear that---and more than a bit surprised, actually.  I
didn't think that the committee would be willing to break existing
code, even for the sake of changing an obviously broken feature.
There's going to be some pain for a while while we fix our old code,
but the new semantics of variables declared in for loops (and in if
statements, for that matter) is clearly correct.  My only regret is
that it hadn't always been defined this way.

For the last few months, I've been trying pretty hard to write code
that's correct under both the old and the new rules; all that means,
of course, is that if I have more than one for loop in a single
function then I use a different iteration variable for each.

--

                               --matt




Author: dougm@cs.rice.edu (Doug Moore)
Date: 4 Mar 1995 22:03:29 GMT
Raw View
Matt Austern (matt@physics7.berkeley.edu) wrote:
: In article <D4untt.E0H@ucc.su.OZ.AU> maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
: >  The proposal has passed, by the way.

: I'm glad to hear that

: For the last few months, I've been trying pretty hard to write code
: that's correct under both the old and the new rules; all that means,
: of course, is that if I have more than one for loop in a single
: function then I use a different iteration variable for each.

It is easy to write code for the new definition 'for' that works even
with a compiler that doesn't support it, with the following wonderful
hack that someone I can't identify once posted to this group.

#define for if (0) ; else for

The 'else' supplies implicit braces around the body of the for loop,
limiting the scope of the index variable declared there.

When your compiler provides the new behavior, you can remove the
#definition with no change in program behavior.

Doug Moore
(dougm@cs.rice.edu)




Author: graham@scitec.demon.co.uk (Graham Coles)
Date: Tue, 28 Feb 1995 23:41:57 +0000
Raw View
In article <3it0of$pbp@etca.etca.fr>
           chris@alofi.etca.fr "Christian Millour" writes:

[CM] Sorry folks, I can't resist.
[CM] |> Perhaps it's just me but I formed the habit of writing code like:
[CM] |>    for(int i=0; i<n; i++) { ... } x[i] = 0;

[CM] Blame yourself. I've always felt uncomfortable with the current state
[CM] of affairs and always believed it would be fixed some day. So when I
[CM] need the loop variable outside of the loop body I declare it
[CM] in a separate set of braces ...

I have a strange feeling that all of my C++ loops might start to look
that way after tonight.  Meanwhile, I will consider myself well and truly
blamed, give myself a good horse-whipping and begin rewriting all my for
loops this weekend!

[CM] |> Those less fortunate to have a static scoped variable of the same
[CM] |> name to fall back on will just have to live with the fact that their
[CM] |> programs will just go wrong periodically !!

[CM] It's worse. Not necessarily static. Are you familiar with nested braces?

Perhaps another reason not to change the scope semantics ?

[CM] what will probably happen is that for some years compilers will warn about
[CM] dangerous use (I agree though that it will be difficult to catch all cases).
[CM] Those compilers will probably feature a backward compatibility flag too.
[CM] ...
[CM] The point IMHO might to be consistent with similar constructs for `if'
[CM] and `while' statements, as for instance
[CM]
[CM]   if (A* pA = dynamic_cast<A*>(p)) {
[CM]     // pA in scope within this set of braces. Use A-specific code.
[CM]   } else {
[CM]     // general method, operates on p
[CM]   }
[CM]
[CM] |> What else can I say, "IF IT AIN'T BROKE, DON'T DAMN WELL FIX IT!!!"
[CM]
[CM] It was broken right from the start. I believe BS admitted that long ago.
[CM] <.... shuffling books on my desk .....> Hmmmm. It is mentionned in "the
[CM] Design and Evolution of C++", 3.11.5.1, p 99. I'm pretty sure I've seen
[CM] it in earlier texts though. In the following section an other example
[CM] is given for the `if' statement.

While I set about reading this, perhaps someone could tell me where to
find some up to date information on the proposed changes, all of my 93/94
books seem decidedly out of date!
I did notice an earlier post that seemed to imply that ANSI don't make
their draft C++ documents available over the 'net - How up to date is
Stoustrup's D+E ? Presumably ANSI have covered some ground since that
was published.

[CM] It's a tough world. The moral might be that it pays to be sceptical about
[CM] the constructs you're being offered, and be very sure you understand
[CM] their purpose before using them. I'm curious about the kind of horrors
[CM] you will make out of RTTI when it's in common use... (just kidding,
[CM] no mortal offense meant, just balancing heat according to fundamental
[CM] thermodynamics principles... BTW I'm not part of the standards committee,
[CM] they might have other reasons).
[CM]
[CM] Nice day, isn't it ?

Just wonderful, especially for newly formed sceptics whose bright yellow
CD (ver 6.1) doesn't know about RTTI, bools etc.
Perhaps this is in the forthcoming ver 7 <sigh>

--
Graham Coles               | "Things would be different if I were an android,
graham@scitec.demon.co.uk  |  I'd be called 'Marvin' for a start"





Author: vandevod@pleiades.cs.rpi.edu (David Vandevoorde)
Date: 3 Mar 1995 15:48:31 GMT
Raw View
In article <D4untt.E0H@ucc.su.OZ.AU>,
John Max Skaller <maxtal@Physics.usyd.edu.au> wrote:
>In article <793836691snz@scitec.demon.co.uk>,
>Graham Coles <graham@scitec.demon.co.uk> wrote:
>>I have read in a professional C++ magazine that ANSI were planning on
>>changing the for loop variable scope so that the loop variable ceases
>>to exist on exit ....
[ ... snipp ...]
>
> The proposal has passed, by the way.
[ ... more snip ... ]
>
>>Have they not heard of the term 'upward compatibility' ??
>
[ ... always snipp ... ]
>variable should be too. In particular, the following
>rubbish is fixed:
>
> for(int i=....
> for(int i= ... // ERROR duplicate declaration of i
>
>A loop is a block, and the control variable -- as in PASCAL --
>should be nested in the block if declared in it.

Although I agree with the "consistency" argument, the original
poster's point remains valid (I think): I expect that there is
a lot of code out there that relies on the extended scope of
induction variables declared in the for-clause. For one, many
must have (looking at my own code :) been frustrated at the
"rubbish" you mention above and replaced it by:

 for (int i = ...
 for (i = ...

Has there been any thought about keeping the "old" behavior as
a default and allowing the "new" behavior with some specific
notation? Maybe,

 for (private int i =... // OK, i only in for-block scope
 for (int i = ...  // OK, i's scope extends to end of
    // surrounding block.
 for (int i = ... // Error: i declared twice

 Daveed
>--
>        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
> Maxtal Pty Ltd,
>        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
>        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189






Author: graham@scitec.demon.co.uk (Graham Coles)
Date: Sun, 26 Feb 1995 22:11:31 +0000
Raw View
I have read in a professional C++ magazine that ANSI were planning on
changing the for loop variable scope so that the loop variable ceases
to exist on exit ....

Are they mad ?
Have they not heard of the term 'upward compatibility' ??
When are they going to retract this suggestion ...

Perhaps it's just me but I formed the habit of writing code like:

   for(int i=0; i<n; i++) {
  ...
 }
 x[i] = 0;

many years ago.  I'm sure I can't be the only one to find this notation
convenient and after all this time it is simply second nature to me.

Now it seems, ANSI are trying to introduce bugs into peoples programs
by changing the rules to the point where, if you listen hard enough, you
can hear literally millions of lines of code breaking because of this
change ...

... and the lucky ones will be those whose once debugged programs now
scream "Undefined variable 'i' on line ...." upon recompilation!

Those less fortunate to have a static scoped variable of the same name
to fall back on will just have to live with the fact that their programs
will just go wrong periodically !!

This appears to be plain stupidity; the end result, no doubt, is that
all responsible C++ programmers will abandon this method and revert to
the only guaranteed (C style) portable construction:

{
 int i;
 ...
   for(i=0; i<n; i++) {
  ...
 }
 x[i] = 0;
}

So what's the point?  All that ANSI will have achieved is to waste God
knows how many hours of (everyone else's) programming time fixing errors
that they have introduced and probably no-one will use the new feature!

Perhaps someone from the standards committee would like to explain why
they thought this was such a good idea (*please* do, I'd love to know why).

What else can I say, "IF IT AIN'T BROKE, DON'T DAMN WELL FIX IT!!!"

( Apologies for the 'heated' content, but I think it is warranted )
--
Graham Coles,                          | "That's one small login for man ...
graham@scitec.demon.co.uk              |  ... one giant phone bill from BT"





Author: chris@alofi.etca.fr (Christian Millour)
Date: 27 Feb 1995 17:05:18 GMT
Raw View
Sorry folks, I can't resist.

In article <793836691snz@scitec.demon.co.uk>, graham@scitec.demon.co.uk (Graham Coles) writes:
|> I have read in a professional C++ magazine that ANSI were planning on
|> changing the for loop variable scope so that the loop variable ceases
|> to exist on exit ....

a Good Thing.

|>
|> Are they mad ?

No.

|> Have they not heard of the term 'upward compatibility' ??

Have you heard about `backward compatibility' mode ?

|> When are they going to retract this suggestion ...

I hope they won't. As a matter of facts your post came as a pleasant
surprise to me. Not that it would change anything in my code anyway.

|>
|> Perhaps it's just me but I formed the habit of writing code like:
|>
|>    for(int i=0; i<n; i++) {
|>   ...
|>  }
|>  x[i] = 0;
|>
|> many years ago.  I'm sure I can't be the only one to find this notation
|> convenient and after all this time it is simply second nature to me.
|>

Blame yourself. I've always felt uncomfortable with the current state
of affairs and always believed it would be fixed some day. So when I
need the loop variable outside of the loop body I declare it
in a separate set of braces (see below). It makes much more sense with
the spirit of the language and with the rationale for moving declaration
to the point of first use.

|> Now it seems, ANSI are trying to introduce bugs into peoples programs
|> by changing the rules to the point where, if you listen hard enough, you
|> can hear literally millions of lines of code breaking because of this
|> change ...
|>
|> ... and the lucky ones will be those whose once debugged programs now
|> scream "Undefined variable 'i' on line ...." upon recompilation!
|>
|> Those less fortunate to have a static scoped variable of the same name

It's worse. Not necessarily static. Are you familiar with nested braces?

|> to fall back on will just have to live with the fact that their programs
|> will just go wrong periodically !!

what will probably happen is that for some years compilers will warn about
dangerous use (I agree though that it will be difficult to catch all cases).
Those compilers will probably feature a backward compatibility flag too.

|>
|> This appears to be plain stupidity; the end result, no doubt, is that
|> all responsible C++ programmers will abandon this method and revert to
|> the only guaranteed (C style) portable construction:
|>
|> {
|>  int i;
|>  ...
|>    for(i=0; i<n; i++) {
|>   ...
|>  }
|>  x[i] = 0;
|> }

Not quite right. The ellipsis above is probably misplaced. The loop
variable (as IMHO *any* variable) should enter and leave scope as
tightly as possible. My own coding practice follows when I need i outside
of the loop (as a matter of facts, this is precisely how I used to code
in plain C).
  {
     ...
     {
        int i;
        for (i = 0; ...) {...}
        x[i] = 0;
     }
     ...
  }

or

  {
     ...
     {
 A a(whatever);
        for ( ; ....) {...}
        // use a
     }
     ...
  }

which I tend to use when a is a reference or a class object with a
constructor. I don't consider the extra set of braces above to be
outrageous.

|>
|> So what's the point?  All that ANSI will have achieved is to waste God
|> knows how many hours of (everyone else's) programming time fixing errors
|> that they have introduced and probably no-one will use the new feature!
|>

The point IMHO might to be consistent with similar constructs for `if' and
`while' statements, as for instance

  if (A* pA = dynamic_cast<A*>(p)) {
    // pA in scope within this set of braces. Use A-specific code.
  } else {
    // general method, operates on p
  }

|> Perhaps someone from the standards committee would like to explain why
|> they thought this was such a good idea (*please* do, I'd love to know why).
|>
|> What else can I say, "IF IT AIN'T BROKE, DON'T DAMN WELL FIX IT!!!"
|>

It was broken right from the start. I believe BS admitted that long ago.
<.... shuffling books on my desk .....> Hmmmm. It is mentionned in "the
Design and Evolution of C++", 3.11.5.1, p 99. I'm pretty sure I've seen it
in earlier texts though. In the following section an other example is given
for the `if' statement.

I'm not sure the suggestion will pass. Anyway, for reasons stated above,
I don't give a damn.

|> ( Apologies for the 'heated' content, but I think it is warranted )

It's a tough world. The moral might be that it pays to be sceptical about
the constructs you're being offered, and be very sure you understand their
purpose before using them. I'm curious about the kind of horrors you will
make out of RTTI when it's in common use... (just kidding, no mortal
offense meant, just balancing heat according to fundamental thermodynamics
principles... BTW I'm not part of the standards committee, they might have
other reasons).

Nice day, isn't it ?

|> --
|> Graham Coles,                          | "That's one small login for man ...
|> graham@scitec.demon.co.uk              |  ... one giant phone bill from BT"
|>

-- chris@etca.fr
Le monde entier est un cactus, il est impossible de s'asseoir (J. Dutronc)