Variables in "for" Loop

V

Volkan YAZICI

Hi,

Why does

for (list<string> newlines = frame(oldlines),
list<string>::iterator line = newlines.begin();
line != newlines.end();
++line)

not work, while

list<string> newlines = frame(oldlines);
for (list<string>::iterator line = newlines.begin();
line != newlines.end();
++line)

does?


Regards.
 
J

Johannes Schaub (litb)

Volkan said:
Hi,

Why does

for (list<string> newlines = frame(oldlines),
list<string>::iterator line = newlines.begin();
line != newlines.end();
++line)

not work, while

list<string> newlines = frame(oldlines);
for (list<string>::iterator line = newlines.begin();
line != newlines.end();
++line)

does?


Regards.

Because you cannot declare variables of that much differing types in a
forloop's init declaration. It must be a single block-declaration. So all
declared names must have the same base-type, tho they can differ by
pointer/reference/function declarators. A way around this is to use a
nameless struct


for(struct { list<string> newlines; list<string>::iterator line; }
loop = { frame(oldlines), loop.newlines.begin() };
loop.line != loop.newlines.end(); ++loop.line)
{ ... }
 
V

Volkan YAZICI

Because you cannot declare variables of that much differing types in a
forloop's init declaration. It must be a single block-declaration. So all
declared names must have the same base-type, tho they can differ by
pointer/reference/function declarators. A way around this is to use a
nameless struct

for(struct { list<string> newlines; list<string>::iterator line; }
    loop = { frame(oldlines), loop.newlines.begin() };
    loop.line != loop.newlines.end(); ++loop.line)
{ ... }

Thanks so much for the prompt reply. Is it possible to freely reach
this information via internet? (E.g. Is there any web page for the
syntax of "for" statement?)


Regards.
 
J

Johannes Schaub (litb)

Johannes said:
Because you cannot declare variables of that much differing types in a
forloop's init declaration. It must be a single block-declaration. So all
declared names must have the same base-type, tho they can differ by
pointer/reference/function declarators. A way around this is to use a
nameless struct


for(struct { list<string> newlines; list<string>::iterator line; }
loop = { frame(oldlines), loop.newlines.begin() };
loop.line != loop.newlines.end(); ++loop.line)
{ ... }

Ah, seems I've fallen into a trap. C++03 does not define the order in which
the members are initialized, neither the order in which the elements in the
initializer list are evaluated. C++0x specifies the order in which the
elements of the initializer list are evaluated, but doesn't specify the
order in which the elements are initialized either, it seems.

So the "loop.newlines" is not safe to use because there is no guaranteed
that the list was already created at that point. :(
 
B

Balog Pal

Johannes Schaub (litb) said:
pointer/reference/function declarators. A way around this is to use a
nameless struct


for(struct { list<string> newlines; list<string>::iterator line; }
loop = { frame(oldlines), loop.newlines.begin() };
loop.line != loop.newlines.end(); ++loop.line)
{ ... }

Wow, never thought of this neat trick before...
 
A

Andrea Venturoli

Il 09/01/10 22:30, Balog Pal ha scritto:
Wow, never thought of this neat trick before...

By the way, I remember older gcc versions would accept:

for ({int a=0; double b=0;} a!=10;++a) foo(a,b);

I guess a block-declaration was accepted, altough C++ allows the first
part of the for loop to be a *simple*-declaration.

Newer gccs won't accept this anymore.


bye
av.
 
J

Johannes Schaub (litb)

Andrea said:
Il 09/01/10 22:30, Balog Pal ha scritto:

By the way, I remember older gcc versions would accept:

for ({int a=0; double b=0;} a!=10;++a) foo(a,b);

I guess a block-declaration was accepted, altough C++ allows the first
part of the for loop to be a *simple*-declaration.

Newer gccs won't accept this anymore.
Yep, I confused the terms. It's a simple-declaration that's allowed, not a
block-declaration ("{ ... }" wouldn't even be a block-declaration. It's just
a statement). If block-declarations were allowed, one could put using
declarations/directives etc..

Now in C++0x, I've no idea about rules for in-class initializers, but I
wonder whether it's valid to say the following?

for(struct { int a = 0; double b = 0; } loop; ....)

I.e to make use of those new initializers instead of using aggregate
initialization?
 
S

Seungbeom Kim

Ah, seems I've fallen into a trap. C++03 does not define the order in which
the members are initialized, neither the order in which the elements in the
initializer list are evaluated. C++0x specifies the order in which the
elements of the initializer list are evaluated, but doesn't specify the
order in which the elements are initialized either, it seems.

So the "loop.newlines" is not safe to use because there is no guaranteed
that the list was already created at that point. :(

I'm pretty sure that the members are initialized in the order they are
declared in the struct definition, even in C++03 (12.6.2/5).

However, I agree that this alone doesn't make the technique safe to use,
if the order of evaluation of the expressions in the initializer list is
not specified.
 
J

Johannes Schaub (litb)

Seungbeom said:
I'm pretty sure that the members are initialized in the order they are
declared in the struct definition, even in C++03 (12.6.2/5).

I think that wording is only about the ctor-initializer in a constructor
definition. I was using aggregate initialization though :(
However, I agree that this alone doesn't make the technique safe to use,
if the order of evaluation of the expressions in the initializer list is
not specified.

Too bad. I remember some people having asked about this issue in the past.
Would it not be a good thing if C++0x had some guarantees about this?
 
S

Seungbeom Kim

I think that wording is only about the ctor-initializer in a constructor
definition. I was using aggregate initialization though :(

A class may not have a user-defined constructor and be an aggregate
at the same time, so there's no serious inconsistency of the same class
being initialized in one order here and in another order there,
but I would be surprised if the standard did mean to allow any order
in aggregate initialization while mandating the declaration order
regardless of the mem-initializers order in user-defined construction.
Yes, I agree that the standard may not be clear, and it may be a defect.
Too bad. I remember some people having asked about this issue in the past.
Would it not be a good thing if C++0x had some guarantees about this?

Maybe yes, maybe no. I just wonder whether it was a deliberate decision
to leave the evaluation order of the expressions unspecified, just as
that for the subexpressions in a full expression.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,371
Latest member
Brkaa

Latest Threads

Top