473,385 Members | 1,518 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

redefinition inside for loop

On my visual c++ compiler, I compiled code which contained something
like

for( int i =0; i < 5; i++)

{ double x =5;}

I expected it to give a compiler error because x is being redefined
and redeclared each time through the loop.

Is there an ANSI standard that says that you can redefine variables
inside a for-loop?

Or is this regarded as not being a redefinition because the definition
is only written once?

I'd be grateful if someone could explain why the above code compiles
but {//some code
double x=5; double x=6; // more code} gives a redefinition error.

Thank you,

Paul Epstein

Oct 25 '07 #1
9 7485
pa**********@att.net wrote:
On my visual c++ compiler, I compiled code which contained something
like

for( int i =0; i < 5; i++)

{ double x =5;}

I expected it to give a compiler error because x is being redefined
and redeclared each time through the loop.
Why do you consider that a problem?
Is there an ANSI standard that says that you can redefine variables
inside a for-loop?
What do you mean by "redefine"? You define it only once. it gets created at
the point of definition and destroyed at the end of the scope, just like
any other (non-static) local variable. So on each iteration it gets created
and destroyed.
Or is this regarded as not being a redefinition because the definition
is only written once?

I'd be grateful if someone could explain why the above code compiles
but {//some code
double x=5; double x=6; // more code} gives a redefinition error.
Because you define two variables with the same name in the same scope. In
your for loop, you don't have that.

Oct 25 '07 #2
On 2007-10-25 05:54, pa**********@att.net wrote:
On my visual c++ compiler, I compiled code which contained something
like

for( int i =0; i < 5; i++)

{ double x =5;}

I expected it to give a compiler error because x is being redefined
and redeclared each time through the loop.

Is there an ANSI standard that says that you can redefine variables
inside a for-loop?
No, but there is one that allows you to redefine a variable in a new scope.
Or is this regarded as not being a redefinition because the definition
is only written once?

I'd be grateful if someone could explain why the above code compiles
but {//some code
double x=5; double x=6; // more code} gives a redefinition error.
You can not have two variables with the same name in the same scope.

--
Erik Wikström
Oct 25 '07 #3
On Oct 25, 4:54 am, pauldepst...@att.net wrote:
On my visual c++ compiler, I compiled code which contained something
like

for( int i =0; i < 5; i++)

{ double x =5;}

I expected it to give a compiler error because x is being redefined
and redeclared each time through the loop.

Is there an ANSI standard that says that you can redefine variables
inside a for-loop?

Or is this regarded as not being a redefinition because the definition
is only written once?

I'd be grateful if someone could explain why the above code compiles
but {//some code
double x=5; double x=6; // more code} gives a redefinition error.

Thank you,

Paul Epstein
x is created within the scope of the loop. in your case it's put on
the stack. At the end of the loop, the stack unwinds and it gets
removed. You then start through the loop again and create a new
variable called x on the stack. It uses the same slot in the stack but
is still a different object.

Consider:

for (int i = 0; i < 5; ++i)
{
double* x = new double(5);
delete x;
}

This does the same thing as your code but on the heap so it might be a
little clearer.

Oct 25 '07 #4
On Oct 25, 9:48 am, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-10-25 05:54, pauldepst...@att.net wrote:
On my visual c++ compiler, I compiled code which contained something
like
for( int i =0; i < 5; i++)
{ double x =5;}
I expected it to give a compiler error because x is being redefined
and redeclared each time through the loop.
Is there an ANSI standard that says that you can redefine
variables inside a for-loop?
No, but there is one that allows you to redefine a variable in
a new scope.
It's a bit trickier than that; in this case, I think that the
for introduces a new scope. Think of it for a moment:

for ( int i = 0 ; i < 10 ; ++ i )
MyClassType c ;

If the for doesn't introduce a new scope, where does c get
destructed? (In the early days, this wasn't that clear, and a
lot of compilers would call the destructor of c at the next }.
Even if the conditions of the for loop meant that it was never
executed.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 25 '07 #5
On Oct 25, 6:54 am, pauldepst...@att.net wrote:
On my visual c++ compiler, I compiled code which contained something
like

for( int i =0; i < 5; i++)

{ double x =5;}

I expected it to give a compiler error because x is being redefined
and redeclared each time through the loop.

Is there an ANSI standard that says that you can redefine variables
inside a for-loop?

Or is this regarded as not being a redefinition because the definition
is only written once?

I'd be grateful if someone could explain why the above code compiles
but {//some code
double x=5; double x=6; // more code} gives a redefinition error.
let us call every pair of { and } a block statment.then any acceptable
identifier can be defined exactly once in each block statement.A block
nested in another block can access the identifiers defined in the
nesting block or hide them via redefining them .

regards,
FM.

Oct 25 '07 #6
James Kanze wrote:
Is there an ANSI standard that says that you can redefine
variables inside a for-loop?
>No, but there is one that allows you to redefine a variable in
a new scope.

It's a bit trickier than that; in this case, I think that the
for introduces a new scope. Think of it for a moment:

for ( int i = 0 ; i < 10 ; ++ i )
MyClassType c ;

If the for doesn't introduce a new scope, where does c get
destructed?
Same for the variable i.

Oct 25 '07 #7
On Oct 25, 6:47 pm, Rolf Magnus <ramag...@t-online.dewrote:
James Kanze wrote:
Is there an ANSI standard that says that you can redefine
variables inside a for-loop?
No, but there is one that allows you to redefine a variable in
a new scope.
It's a bit trickier than that; in this case, I think that the
for introduces a new scope. Think of it for a moment:
for ( int i = 0 ; i < 10 ; ++ i )
MyClassType c ;
If the for doesn't introduce a new scope, where does c get
destructed?
Same for the variable i.
Yes. But that's also an intentional change.

As far as I can tell, early (pre-standard) C++ didn't really
specify the lifetime of something like c, above. Generally
speaking, the rule was that the variable had a scope until the
end of the block, which would (logically) mean:

for ( int i = 0 ; i < 10 ; i ++ )
MyClassType c ;
c.doSomething() ; // c still valid here !!!

IIRC, many early compilers did allow this, calling the
constructor of c each time through the loop (and not at all if
the loop executed 0 times), and calling the destructor once at
the end of the enclosing block. As you can imagine, this didn't
work out too well in practice. (IIRC, too, CFront---which only
destructed temporaries at the end of the block---did the same
thing with temporaries. Including any generated in condition or
the increment parts of the for. I definitely once had a problem
with a temporary returned by the increment part. And while
something like the above is really unlikely in actual code,
temporaries aren't.)

Because of the obvious problems, the rule was very quickly
changed that objects declared in a conditional statement had the
scope of that statement; i.e. c, above, had the scope of the for
statement. (I think this change was even before standardization
began---in fact, it may have been the rule from the start, and
just have been poorly implemented by the compilers I was using.)

When dynamic_cast was introduced, the grammar was modified to
allow a declaration in the condition; this declaration was given
the scope of the statement. Only after that was it felt that
this made the longer scope of the variable in the initialization
part of the for inconsistent, so its scope was changed. (There
had been a proposal earlier to change it; at that time, it was
generally agreed that the scope should have been that of the for
statement, but that changing it at that time would involve
breaking too much code. By the time dynamic_cast was added,
however, the dynamics of the committee had changed, and nobody
cared about existing code.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 26 '07 #8
On Oct 26, 11:16 am, James Kanze <james.ka...@gmail.comwrote:
On Oct 25, 6:47 pm, Rolf Magnus <ramag...@t-online.dewrote:
James Kanze wrote:
Is there an ANSI standard that says that you can redefine
variables inside a for-loop?
>No, but there is one that allows you to redefine a variable in
>a new scope.
It's a bit trickier than that; in this case, I think that the
for introduces a new scope. Think of it for a moment:
for ( int i = 0 ; i < 10 ; ++ i )
MyClassType c ;
If the for doesn't introduce a new scope, where does c get
destructed?
Same for the variable i.

Yes. But that's also an intentional change.

As far as I can tell, early (pre-standard) C++ didn't really
specify the lifetime of something like c, above. Generally
speaking, the rule was that the variable had a scope until the
end of the block, which would (logically) mean:

for ( int i = 0 ; i < 10 ; i ++ )
MyClassType c ;
c.doSomething() ; // c still valid here !!!

IIRC, many early compilers did allow this, calling the
constructor of c each time through the loop (and not at all if
the loop executed 0 times), and calling the destructor once at
the end of the enclosing block. As you can imagine, this didn't
work out too well in practice. (IIRC, too, CFront---which only
destructed temporaries at the end of the block---did the same
thing with temporaries. Including any generated in condition or
the increment parts of the for. I definitely once had a problem
with a temporary returned by the increment part. And while
something like the above is really unlikely in actual code,
temporaries aren't.)

Because of the obvious problems, the rule was very quickly
changed that objects declared in a conditional statement had the
scope of that statement; i.e. c, above, had the scope of the for
statement. (I think this change was even before standardization
began---in fact, it may have been the rule from the start, and
just have been poorly implemented by the compilers I was using.)

When dynamic_cast was introduced, the grammar was modified to
allow a declaration in the condition; this declaration was given
the scope of the statement. Only after that was it felt that
this made the longer scope of the variable in the initialization
part of the for inconsistent, so its scope was changed. (There
had been a proposal earlier to change it; at that time, it was
generally agreed that the scope should have been that of the for
statement, but that changing it at that time would involve
breaking too much code. By the time dynamic_cast was added,
however, the dynamics of the committee had changed, and nobody
cared about existing code.)
Sorry to terminate again;I can not see what the scope of for
initializer is .I used to take the following two as equivalent code:

_1st:
for(int init =0 ;condition ;inrement)
statement;

_2nd:
start_loop:{
int init=0;
for(;condition;increment)
{statement;};
};//destroy init

regards,
FM.

Oct 27 '07 #9
On Oct 27, 11:08 am, terminator <farid.mehr...@gmail.comwrote:
On Oct 26, 11:16 am, James Kanze <james.ka...@gmail.comwrote:
Sorry to terminate again ;I can not see what the scope of for
initializer is. I used to take the following two as equivalent
code:
_1st:
for(int init =0 ;condition ;inrement)
statement;
_2nd:
start_loop:{
int init=0;
for(;condition;increment)
{statement;};

};//destroy init
They are at present. They didn't used to be; in the (now fairly
distant) past, the equivalent of the first was simply:

int init=0 ;
for ( ; condition ; increment )
statement ;

I don't think that there was even an implicit {...} around the
statement, and there certainly wasn't one around the for
itself; any variables declared in the initialization part had a
lifetime corresponding to that of the block surrounding the for.
And code like:

for ( int i = 0 ; i < last && ! condition ; i ++ ) {
}
return i ;

was quite frequent.

The fact that "statement" had a scope until the end of the block
is an obvious oversight, since it cannot be made to work. It
was fixed very, very early. At more or less the same time, the
committee considered the possibility of reducing the scope of a
variable declared in the initialization part of a for. The
consensus at the time was, I think, that while it would be
cleaner, there was to much code in existence like the example
immediately above, which would break, and that such a change
would be irresponsible.

Much, much later---as part of the dynamic_cast proposal---the
possibility of defining a variable in a "condition" (if, while
or second part of a for) was introduced. After that, it was
felt that having different scopes for two variables, both
defined in a for loop, was too counter-intuitive, so the scope
of the variable in the initialization part of the for loop was
changed. (Responsibility wasn't an "in" word in the committee
at that point in time. IMHO, being able to declare a variable
in a condition is, itself, a mis-feature, but since no one is
required to use it, it doesn't bother me too much. Breaking
existing code did, but there wasn't much I could do about it.)

This change was fairly late in the standards proceedings; just
before CD1, I think. Many compilers didn't implement it
immediately, probably to avoid breaking existing code. Even
today, most compilers have an option to use the old for scope,
precisely so that old code can compile.

Note that the change can silently change the semantics of a
program. Consider:

static int i = 2 ;

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

f(10) will return 10 under the old rules, 2 under the new. In
practice, I doubt that this is ever a problem in well written
code, since you normally wouldn't give a variable in local scope
the same name as one with namespace (or class) scope. (A good
general rule is that the length of a name is inversely
proportional to its visibility. Local variables, particularly
loop control variables, can have very, very short names, like i,
where as anything visible outside a single function requires a
somewhat longer, more meaningful name.)

FWIW: the version of g++ that I have on my machine (4.1.2) will
issue a warning for this code, by default (and use the new
rule). It also has an option (-fno-for-scope) to silently use
the old rule. (I had thought that -ffor-scope would turn off
the warning, but it doesn't seem to.)

Also, I believe that VC++ 6.0 (still widely used!) still
implemented the old rule---it did appear before the standard was
adopted.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 28 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: lomat | last post by:
Hello, While compiling a file, I get following error .... ================================= /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/include/g++/type_traits.h:14 2: redefinition of...
13
by: Gernot Frisch | last post by:
What does the standart say: for (long i=0; i<0; ++i) ; for (myclass i=0; i<0; ++i); is it allowed? i only is defined in the for-loop space, isn't it? VC6 gives me an *error*, not just a...
1
by: squallions | last post by:
Hi I doing my c++ homework and stuck on error 'class' type redefinition. I have 5 classes. First class is base class. The next two classes are derived from the first class. The next two...
9
by: john hrdo | last post by:
Hey, This might well be a naive question, please be patient. Is it possible to compile a C program including two libraries lib1 and lib2 which have both a function with same name, e.g....
4
by: junaidnaseer | last post by:
Hi ! I am facing a problem that I have defined a function which when called in the same file generates an error as follows; " visual c error C2371 redefinition basic types see...
1
by: Alex | last post by:
Hello all, I have a very stupid problem that is driving me crazy...so plz if anyone ever saw this, I would like him to help me :) I have static MFC application in MSVC++ 6.0 (named Example)....
7
by: Samant.Trupti | last post by:
Hi, I am getting this error. error C2371: 'LineCollection' : redefinition; different basic types I have 'LineCollection' defined in two header files in one project Like "typedef...
5
by: sgurukrupagmailcom | last post by:
Hi, I haven't come accross an elegant solution to a design problem that I show below. Have a look at the piece of code here: class Exc { Exc () { System.out.println ("Haribol"); }
1
by: JavaJon | last post by:
Hello, I'm Jon. I've recently picked up Java after using a "gimmick" programming language called GML ( Game Maker Language ). I've read a lot of tutorials and even a Java for Dummies *.pdf book....
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.