Page 1 of 2
ANDs & ORs in If statements
Posted: Tue Jan 27, 2009 5:25 pm
by endo
Hi,
In if statements it exits on first "false" when condititions ANDed, but it does not exit on first "true" when condiditons ORed. Is it a design feature? As I know it is different some other languages. Please look at the examples below.
Code: Select all
Procedure test()
MessageRequester("test","test")
ProcedureReturn #True
EndProcedure
a = 0
If a = 1 And test() ; test() won't be called, and it is good..
MessageRequester("ok","ok")
EndIf
Code: Select all
Procedure test()
MessageRequester("test","test")
ProcedureReturn #True
EndProcedure
a = 1
If a = 1 Or test() ; test() will be called
MessageRequester("ok","ok")
EndIf
Re: ANDs & ORs in If statements
Posted: Tue Jan 27, 2009 5:42 pm
by Little John
endo wrote:Code: Select all
Procedure test()
MessageRequester("test","test")
ProcedureReturn #True
EndProcedure
a = 1
If a = 1 Or test() ; test() will be called
MessageRequester("ok","ok")
EndIf
test is
not called on my system (PB 4.30 x86 on Windows), so I can't reproduce your finding.
With which PureBasic version did you encounter this?
Regards, Little John
Re: ANDs & ORs in If statements
Posted: Tue Jan 27, 2009 6:00 pm
by endo
Little John wrote:
test is not called on my system (PB 4.30 x86 on Windows), so I can't reproduce your finding.
With which PureBasic version did you encounter this?
Regards, Little John
its strange!? I'm using PB 4.30 x86 on Windows XP Pro.
Posted: Tue Jan 27, 2009 6:19 pm
by srod
Works fine here as well in that test() is not called. (PB 4.3, Vista 32).
Posted: Tue Jan 27, 2009 6:22 pm
by freak
endo:
I think you are mistaking the "Ok" Messagerequester() for the "test" one.
In the second example, there has to be 1 requester, since the If evaluates to true. There is only something wrong if you get 2 requesters.
Posted: Tue Jan 27, 2009 7:53 pm
by Marco2007
I would expect two requesters.
...and I get two, when doing this:
Code: Select all
Procedure test()
MessageRequester("test","test")
ProcedureReturn #True
EndProcedure
a = 1
b=test()
If a = 1 Or test() ; test() will be called
MessageRequester("ok","ok")
EndIf
or
Code: Select all
Procedure test()
MessageRequester("test","test")
ProcedureReturn #True
EndProcedure
a = 1
b=test()
If a = 1 Or b ; test() will be called
MessageRequester("ok","ok")
EndIf
and try this:
Code: Select all
Procedure test()
MessageRequester("test","test")
ProcedureReturn #True
EndProcedure
a = 1
b=test()
If a = 1 Or test() ; test() will be called
MessageRequester("ok","ok")
EndIf
If a = 1 Or test() ; test() will be called
MessageRequester("ok","ok")
EndIf
Posted: Tue Jan 27, 2009 8:02 pm
by freak
Marco2007 wrote:I would expect two requesters.
...and I get two, when doing this:
Of course you get two. You moved the function call out of the If statement.
In the original example, the expected number of requester is:
0 for the And example, because the statement is false even without the evaluation of test()
1 for the Or example, because the statement is true even without the test() (so you get only the requester inside the If)
This is called "Short-circuit evaluation" and a lot of languages do it this way, because it is faster and it allows to write code like this:
Code: Select all
If *Pointer <> 0 And PeekL(*Pointer) <> 0
; something
EndIf
If the second part got evaluated always, this code would crash whenever *Pointer is 0. But since the second part only gets tested if the first part was true, this code works without problems.
Posted: Tue Jan 27, 2009 8:22 pm
by Marco2007
freak wrote:This is called "Short-circuit evaluation" and a lot of languages do it this way, because it is faster and it allows to write code like this: ....
.......
But since the second part only gets tested if the first part was true
I didn`t know that, although it makes sense!
Thank you

Posted: Tue Jan 27, 2009 10:20 pm
by idle
+ 1 on the didn't know.
Posted: Tue Jan 27, 2009 10:29 pm
by Marco2007
Hm?
Posted: Wed Jan 28, 2009 9:08 am
by endo
I could swear that test() function was called yesterday, but I guess Freak is right, it is not called if a=1.
Sorry for wasting your time
Code: Select all
Procedure test()
MessageRequester("test","test")
ProcedureReturn #True
EndProcedure
a = 1
If a = 1 Or test() ; test() will *NOT* be called
MessageRequester("ok","ok")
EndIf
Posted: Wed Jan 28, 2009 12:23 pm
by srod
Aye the short circuit evaluation is very useful and if this was ever changed all of my programs would instantly crash!

Posted: Wed Jan 28, 2009 12:57 pm
by endo
srod wrote:Aye the short circuit evaluation is very useful and if this was ever changed all of my programs would instantly crash!

yep, most useful cases are:
Code: Select all
If TryOpenScreen(320,200) Or TryOpenScreen(640,480) Or TryOpenScreen(800,600)
;ok
Else
;error
EndIf
And;
Code: Select all
If OpenConsole() And Init() And OpenWindow()
;ok
End If
So Init() can give console output, and OpenWindow() is not called if init failed.
Posted: Wed Jan 28, 2009 7:18 pm
by Marco2007
idle wrote:+ 1 on the didn't know.
What does that mean?
Posted: Wed Jan 28, 2009 7:22 pm
by Kaeru Gaman
Marco2007 wrote:idle wrote:+ 1 on the didn't know.
What does that mean?
that does just mean that idle didn't know that, too, just like you.
