Game Development Community

Ifs with ands and ors

by J Sears · in Torque Game Builder · 04/17/2007 (4:32 pm) · 8 replies

If I write an if that represents this if( A && B || C && D && E) does that get translated as A and B or C and D and E, or does it come out as something more like A and B or A and C and D and E, I think it works out as the first case but I just wanted to make sure.

#1
04/17/2007 (4:41 pm)
J Sears, thats 'poor' coding ... ;)

if( ((%a && %b) || (%c && %d)) && %e)
{
}

Note the lovely use of parenthesis to ensure the proper order ... the && and || statements will be evaluated in that order, && then || ... so it's not (A && (B || C) && D && E) if that's what your original question was though ...

Good tip, when doing numerous things like that, always break them out into parenthesis ... also, keep in mind, Torque evaluates all of those conditions before it returns ... it's not like C/C++ where it returns 'false' at the first sign of a failed condition ... so if any of the code in the condition could 'break' things if executed and a previous condition was not met, place that code in a sub-if ...

if(condition)
{
  if(condition_that_breaks_if_previous_is_not_true)
  {
  }
}

In C, you could just do:

if(condition && condition_that_breaks_if_previous_is_not_true)
{
}



#2
04/17/2007 (6:15 pm)
Very good point about the parenthesis, if I understand what your saying about the difference in script and C is that by putting in the multiple ifs it would help reduce processing time but would still function the same both ways?
thanks again for the quick answer on the parenthesis don't know why that didn't occur to me.
#3
04/17/2007 (8:22 pm)
Well, the multiple if's is to some degree a performance thing ... and in some degree, a way to prevent the engine from crashing ... hehe

Some things require you to have certain things ... take for example something in C++, if I try to call a method of a null object, it'll crash the code ... so ... if(obj != null && obj->isValid) ... is valid ... but in TorqueScript, you can't do things like that ... since the obj->isValid is compared to true/false ... even if obj != null returns false ...

very few instances where this would be a problem ... but they have come up from time to time with me, and moving them out of the same conditional check ... helps ... it also helps with performance, as you noted ... especially if you are checking the return value of functions that perform additional code checks ... that are not necessary to run if something else, easier to evaluate ... is false ... so, when building multiple conditional blocks ... be sure to put the easiest, faster, and shortest conditions first ... and move the more complex ones into a sub-statement ...
#4
04/17/2007 (8:44 pm)
For my money,
the most important thing when coding these sorts of things is the maintainability of the code.
that is, when you or someone else comes along a year later and looks at the expression,
are they going to know without any doubt what the intended logic was ?

Quote:
Torque evaluates all of those conditions before it returns ... it's not like C/C++ where it returns 'false' at the first sign of a failed condition

no kidding? huh. good to know.
#5
04/17/2007 (9:24 pm)
I believe that, at least on TGB version 1.1.3, if you do something like:

if (isObject(obj) && obj.isValid())

it works as you would expect. I mean, it seems to check conditions from left to right and as soon as one is false it stops right there.
#6
04/17/2007 (10:35 pm)
I'm going to have to confirm it, but I'm reasonably sure that TorqueScript does short circuit, at least in most scenarios.

It's possible you found a twig in the compiler with a certain syntax that breaks short circuiting of course, or it's (very!) possible that I'm wrong :)
#7
04/18/2007 (9:27 am)
Stephen, you wrong? Never ...

After reading what Nicolas said, I do recall using the if(isObject(%x) && %x.field) statements quite a bit in my code ... I can't really remember where I ran into this failure to 'short circuit' issue ... but I have come across it, and have since, just stuck to the generic concept of doing what I said above ... however, for short and simple two-condition statements where I check for object presence and then object field value, I do it in a single conditional brace ...

#8
04/18/2007 (10:28 am)
I did two quick tests against my TGE 1.3.5 codebase and the simplest uses of || and && seem to short-circuit correctly:
=> function myTrue() {echo("sending true"); return true;}
=> if (myTrue() || myTrue()) echo ("hey");
sending true
hey

=> function myFalse() {echo("sending false"); return false;}
=> if (myFalse() && myFalse()) echo("hey");
sending false

edit: if it didn't short-circuit, there would be two "sending.." lines in each test.