469,612 Members | 1,610 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

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

Strange abortion of for loop

Hi.

I've come across someting strange. I was trying to make a for-loop
execute repetadly until the function called inside it does not return
true during the entire loop (see program below).

The two lines that confuse me are marked as (1) and (2).

count=0;
bool s(true);
while(s){
s=false;
for (int x=0; x<10; ++x){
//s = s||f(x,count); //(1)
bool tmp =f(x, count); s=s||tmp; //(2)
}
count ++;
}
where f(x,count) is a bool function, returning true for count<3

I thought that they both do the same, ie fun() is executed and bool
variable s = s OR (return from function). However, line (1) will abort
the execution of the for loop already when x=0, whereas line (2) will
let the for loop executs f() 10 times.

Can anyone explain what is going on here and why the two lines don't
behave the same way? Is this the result of some optimization (where the
compiler only looks at changes of variable s and not the side effects of
the function call?)

Full program and outputs for the two different lines are below

regards
/hall

Program code and Outputs
--------------------------

Please scroll down to see the outputs from this program

//-----------------
#include <iostream>
using namespace std;

bool f(int x, int c){
cout << "f("<<x<<","<<c<<")";
return c<3;
}

int main(int argc, char* argv[])
{

bool s(true);
int count(0);

while(s){
s=false;

for (int x=0; x<10; ++x){
//s = s||f(x,count); //(1)
bool tmp =f(x, count); s=s||tmp; //(2)
}

count ++; cout << ", s="<< s<<endl;
}

char a; cin >> a;
return 0;
}
// -------------------
Outputs from program

Case 1) Line (1) is commented out, Output is what I expect:
-----------------
f(0,0)f(1,0)f(2,0)f(3,0)f(4,0)f(5,0)f(6,0)f(7,0)f( 8,0)f(9,0), s=1
f(0,1)f(1,1)f(2,1)f(3,1)f(4,1)f(5,1)f(6,1)f(7,1)f( 8,1)f(9,1), s=1
f(0,2)f(1,2)f(2,2)f(3,2)f(4,2)f(5,2)f(6,2)f(7,2)f( 8,2)f(9,2), s=1
f(0,3)f(1,3)f(2,3)f(3,3)f(4,3)f(5,3)f(6,3)f(7,3)f( 8,3)f(9,3), s=0
-----------------

Case 2) Line (2) is commented out, (1) is not. The for loop gets
executed only once when f() returns true.
-----------------
f(0,0), s=1
f(0,1), s=1
f(0,2), s=1
f(0,3)f(1,3)f(2,3)f(3,3)f(4,3)f(5,3)f(6,3)f(7,3)f( 8,3)f(9,3), s=0
-----------------


--
( - Remove capital X from email to reply - )

Jul 22 '05 #1
4 1292
On Wed, 14 Apr 2004 16:19:19 +0200, hall <Xc***********@yahoo.se> wrote:
Hi.

I've come across someting strange. I was trying to make a for-loop
execute repetadly until the function called inside it does not return
true during the entire loop (see program below).

The two lines that confuse me are marked as (1) and (2).

count=0;
bool s(true);
while(s){
s=false;
for (int x=0; x<10; ++x){
//s = s||f(x,count); //(1)
bool tmp =f(x, count); s=s||tmp; //(2)
}
count ++;
}
where f(x,count) is a bool function, returning true for count<3

I thought that they both do the same, ie fun() is executed and bool
variable s = s OR (return from function). However, line (1) will abort
the execution of the for loop already when x=0, whereas line (2) will
let the for loop executs f() 10 times.

Can anyone explain what is going on here and why the two lines don't
behave the same way? Is this the result of some optimization (where the
compiler only looks at changes of variable s and not the side effects of
the function call?)
Just from what you've said, it seems pretty clear you're not familiar with
the "short circuit" behavior of the || and && operators. In both cases, if
evaluation of the left-hand operand results in a value that "forces" the
logical result of the entire expression, then the right-hand operand is
guaranteed to NOT be evaluated. Otherwise, the right-hand operand is
evaluated and its value is the result of the binary expression.

In your (1), then, f() will not even be called if s is true (and in that
case, s will remain true). If s were false, then s's new value becomes the
result of the call to f().

In your (2), you're calling f unconditionally in the first part, and the
lack of side-effects in the second part means there's nothing surprising
that can happen /there/ either.
-leor

Full program and outputs for the two different lines are below

regards
/hall

Program code and Outputs
--------------------------

Please scroll down to see the outputs from this program

//-----------------
#include <iostream>
using namespace std;

bool f(int x, int c){
cout << "f("<<x<<","<<c<<")";
return c<3;
}

int main(int argc, char* argv[])
{

bool s(true);
int count(0);

while(s){
s=false;

for (int x=0; x<10; ++x){
//s = s||f(x,count); //(1)
bool tmp =f(x, count); s=s||tmp; //(2)
}

count ++; cout << ", s="<< s<<endl;
}

char a; cin >> a;
return 0;
}
// -------------------
Outputs from program

Case 1) Line (1) is commented out, Output is what I expect:
-----------------
f(0,0)f(1,0)f(2,0)f(3,0)f(4,0)f(5,0)f(6,0)f(7,0)f (8,0)f(9,0), s=1
f(0,1)f(1,1)f(2,1)f(3,1)f(4,1)f(5,1)f(6,1)f(7,1)f (8,1)f(9,1), s=1
f(0,2)f(1,2)f(2,2)f(3,2)f(4,2)f(5,2)f(6,2)f(7,2)f (8,2)f(9,2), s=1
f(0,3)f(1,3)f(2,3)f(3,3)f(4,3)f(5,3)f(6,3)f(7,3)f (8,3)f(9,3), s=0
-----------------

Case 2) Line (2) is commented out, (1) is not. The for loop gets
executed only once when f() returns true.
-----------------
f(0,0), s=1
f(0,1), s=1
f(0,2), s=1
f(0,3)f(1,3)f(2,3)f(3,3)f(4,3)f(5,3)f(6,3)f(7,3)f (8,3)f(9,3), s=0
-----------------


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #2
hall wrote:
//s = s||f(x,count); //(1)
bool tmp =f(x, count); s=s||tmp; //(2) Can anyone explain what is going on here and why the two lines don't
behave the same way?


The || operator won't evaluate the right side if the left side is true.
After the first time that f() returns true f() won't be called again
for (1). The code for (2) always calls f().

Jul 22 '05 #3
"hall" <Xc***********@yahoo.se> wrote in message
news:c5**********@eol.dd.chalmers.se...
Hi.

I've come across someting strange. I was trying to make a for-loop
execute repetadly until the function called inside it does not return
true during the entire loop (see program below).

The two lines that confuse me are marked as (1) and (2).

count=0;
bool s(true);
while(s){
s=false;
for (int x=0; x<10; ++x){
//s = s||f(x,count); //(1)

bool tmp =f(x, count); s=s||tmp; //(2)

s=s||tmp means that if s is true it gets reassigned the true value else if
tmp is true s becomes true else if noone is true it is reassigned the false
value since s||tmp evaluates to false.
}
count ++;
}
where f(x,count) is a bool function, returning true for count<3

I thought that they both do the same, ie fun() is executed and bool
variable s = s OR (return from function). However, line (1) will abort
the execution of the for loop already when x=0,

I can't see how line (1) can abort the for loop unless an exception is
thrown or a signal is raised. If you mean that the function call is not
executed 10 times, it happens when after f(x,count) returns true and s gets
that value, at the next evaluations, s evaluates to true so the second
expression is not checked (and thus your functions is not executed at all).
If you want your function to be run 10 times you can make it:

for (int x=0; x<10; ++x){
s = f(x,count) || s;


Ioannis Vranos

Jul 22 '05 #4
On 2004-04-14 16:40 Leor Zolman spoke thusly


Just from what you've said, it seems pretty clear you're not familiar with
the "short circuit" behavior of the || and && operators. In both cases, if
evaluation of the left-hand operand results in a value that "forces" the
logical result of the entire expression, then the right-hand operand is
guaranteed to NOT be evaluated. Otherwise, the right-hand operand is
evaluated and its value is the result of the binary expression.


Thank you. That was exactly what I needed to hear. Now I understand why
things didn't work the way I thought it would.

And thanks to you others who replied too

regards
hall

--
( - Remove capital X from email to reply - )

Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Narya | last post: by
reply views Thread by Michele Laghi | last post: by
36 posts views Thread by Rolloffle | last post: by
2 posts views Thread by Alex | last post: by
20 posts views Thread by SpreadTooThin | last post: by
4 posts views Thread by | last post: by
3 posts views Thread by Rinaldo | last post: by
6 posts views Thread by markus.litz | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.