469,609 Members | 1,634 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,609 developers. It's quick & easy.

Simple scope question


I was paging through Coplien's book "Advanced C++ Programming Styles
and Idioms" this afternoon and found some code that looked something
like

void sort(vector<foo> a)
{
int flip;
do {
for (int i=0, flip = 0; i < a.size(); ++i)
{
for (int j=0; j < i; ++j)
if (a[j] < a[i]) {
swap(a[i],a[j]);
++flip;
}
}
} while (flip > 0);
return;
}
Now the question: This code doesn't work on my compiler, because
the 'flip = 0' shadows the declaration of 'flip' outside the 'do'
loop. The 'for' loop increments one 'flip', while the 'do' loop
evaluates another.

Is this how it's supposed to work? (I think yes.)
Did it work a different way when Coplien wrote the book? (I think no.)
And are there online errata for Coplien's book? (I couldn't find any.)

Thanks,
-Arthur
Jul 19 '05 #1
6 2158
This code doesn't work on my computer, either, but it's not because of
shadowing. It doesn't work because 'vector<foo> a' is passed as a copy
instead of as a reference. You can see this by tracing with the
debugger. Change it to 'vector<foo>& a' and it should work; it does on
my computer.

But...

** How can anyone explain the following scoping weirdness?

I found that the do-loop looks at the outermost of these two 'flip's
that is *initialized*. When I changed the outermost from 'int flip;' to
'int flip = 1;' I got an infinite loop because then (apparently) the
do-loop always looked at the outermost 'flip'.

Suzanne

Arthur J. O'Dwyer wrote:
I was paging through Coplien's book "Advanced C++ Programming Styles
and Idioms" this afternoon and found some code that looked something
like

void sort(vector<foo> a)
{
int flip;
do {
for (int i=0, flip = 0; i < a.size(); ++i)
{
for (int j=0; j < i; ++j)
if (a[j] < a[i]) {
swap(a[i],a[j]);
++flip;
}
}
} while (flip > 0);
return;
}
Now the question: This code doesn't work on my compiler, because
the 'flip = 0' shadows the declaration of 'flip' outside the 'do'
loop. The 'for' loop increments one 'flip', while the 'do' loop
evaluates another.

Is this how it's supposed to work? (I think yes.)
Did it work a different way when Coplien wrote the book? (I think no.)
And are there online errata for Coplien's book? (I couldn't find any.)

Thanks,
-Arthur


Jul 19 '05 #2

"Suzanne Vogel" <su*************@hotmail.com> wrote in message
news:3f**********@news.unc.edu...
** How can anyone explain the following scoping weirdness?

I found that the do-loop looks at the outermost of these two 'flip's
that is *initialized*. When I changed the outermost from 'int flip;' to
'int flip = 1;' I got an infinite loop because then (apparently) the
do-loop always looked at the outermost 'flip'.

Suzanne

void sort(vector<foo> a)
{
int flip;
do {
for (int i=0, flip = 0; i < a.size(); ++i)
{
for (int j=0; j < i; ++j)
if (a[j] < a[i]) {
swap(a[i],a[j]);
++flip;
}
}
} while (flip > 0);
return;
}

Suzanne, it has nothing to do with the first flip variable being initialized
or not (although it DOES have to do with the value it is is being
initialized TO...more on that later). The do itself loop can only 'see' the
first flip instance, because the flip declared inside the the do loop is not
visible at the (outer) scope of the do loop. Everything inside the {} of
the do loop is in an inner scope (if that's the right term), and anything
declared there is out-of-scope outside the {}, including in the while
portion of that loop.

The reason for the infinite loop is that, when you declare it as 1, it will
always be 1 (which is > 0), because the ++flip is operating on the second,
inner flip declaration. If you set it to -1 initially, then the do loop
will excute exactly once, because "-1 > 0" is false.

Howard


Jul 19 '05 #3

On Thu, 3 Jul 2003, Howard wrote:

"Arthur J. O'Dwyer" <aj*@andrew.cmu.edu> wrote in message...

I was paging through Coplien's book "Advanced C++ Programming Styles
and Idioms" this afternoon and found some code that looked something
like

void sort(vector<foo> a)
[Re Suzanne's comment: This wasn't how Coplien actually wrote the
function, of course. It *was* a bubblesort implementation, but
Coplien's focus was on data structures, while my focus was on that
weird nested-scope thing. So I had just been going to put "..."
everywhere, except that "..." is a token, and then once I started
putting pseudo-C++ everywhere it was needed, it ended up being
a whole function. So the type of 'a' is completely irrelevant, and
it's my fault for trying to make the function look complete. :-) ]
{
int flip;
do {
for (int i=0, flip = 0; i < a.size(); ++i)
{
for (int j=0; j < i; ++j)
if (a[j] < a[i]) {
swap(a[i],a[j]);
++flip;
}
}
} while (flip > 0);
return;
}

Now the question: This code doesn't work on my compiler, because
the 'flip = 0' shadows the declaration of 'flip' outside the 'do'
loop. The 'for' loop increments one 'flip', while the 'do' loop
evaluates another.

Is this how it's supposed to work? (I think yes.)
Yes, this is how it is supposed to work.

<snip>
Did it work a different way when Coplien wrote the book? (I think no.)


Yes, for loop variables used to have scope that extended to the whole scope
in which the for loop resided. In this case, the sort function itself.
That made the "flip = 0" simply an assignment (as you intended) and not a
declaration.


So what happened to the first definition of 'flip' under these old rules?
Was it treated as a tentative definition? If it had been initialized
originally, and then "re-initialized" in the for loop, would that be an
error? (Just curious.)
The fix is to initialize flip outside (before) the for loop. Looking at
your code, I image you want to initialize it to 0 where you declared it,
outside the do loop, and simply leave it out of the for loop's statement
altogether.


Actually, the correct place for the initialization is right where Coplien
put it - as the first statement executed after (or before, or concurrently
with) the initialization of 'i' to 0. If you initialize 'flip' outside
the 'do' loop, the bubblesort never terminates.

-Arthur

Jul 19 '05 #4


Howard wrote:
[snip]
The fix is to initialize flip outside (before) the for loop. Looking at
your code, I image you want to initialize it to 0 where you declared it,
outside the do loop, and simply leave it out of the for loop's statement
altogether.


That would break the bubble sort !

But he could move the definition of flip inside the do loop
and initialize it there, thus dropping the second definition
from the for loop:

void sort(vector<foo> a)
{
do {

int flip = 0;

for (int i=0; i < a.size(); ++i)
{
for (int j=0; j < i; ++j)
if (a[j] < a[i]) {
swap(a[i],a[j]);
++flip;
}
}
} while (flip > 0);
return;
}

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #5

"Arthur J. O'Dwyer" <aj*@andrew.cmu.edu> wrote in message
news:Pi***********************************@unix45. andrew.cmu.edu...

So what happened to the first definition of 'flip' under these old rules?
Was it treated as a tentative definition? If it had been initialized
originally, and then "re-initialized" in the for loop, would that be an
error? (Just curious.)


It was actually the definition. The difference comes at the for loop
clause, where the flip=0 was treated as an assignment instead of a
definition. Similar to this:

int a;
....
a = 0;

There you have a declaration, and a later assignment. In the old standard,
it did not matter that the assignment was part of a for loop initializer
clause. That's been changed so that the for loop initializer clause is
consistent with a multiple-declaration statement, such as

int b, a = 0;

Since that's a declaration of a, not a simple assignment, the for loop was
changed to behave the same way.

-Howard
Jul 19 '05 #6

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:3F***************@gascad.at...
altogether.


That would break the bubble sort !
--
Karl Heinz Buchegger
kb******@gascad.at

Quite right. The code was obviously wrong somehow, but I didn't bother to
try to analyze how to fix it properly. (What I was pointing out as a fix
was really how to fix the for loop problem in general, not to solve the
problem with the algorithm implementation.)

-Howard
Jul 19 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by dp | last post: by
12 posts views Thread by Jeff B. | last post: by
4 posts views Thread by Gery D. Dorazio | last post: by
3 posts views Thread by Ryan Pedersen | last post: by
7 posts views Thread by Christian Christmann | last post: by
24 posts views Thread by Michael | last post: by
26 posts views Thread by optimistx | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.