looping constructs - do you use more than one expression in conditional part ?

[Deleted]  

Am intensely interested in how you approach conditions in for and while statements and would appreciate your comments and what you do.

I fear that must do the dreaded nesting stuff like with if's eg: if(a<b) if(c<d) do something;

instead of simply: if(a<b && c<d) do something; //am assuming here that either c or d can cause side effects if executed do to NON early exit when a>=b

.

Please consider:

.

int i,ia[10];
ArrayInitialize(ia,EMPTY);
//...later: 0,1 or more ia[] elements loaded
//and sometime later: search for EMPTY []
i = 0;
while(i<10 && ia[i]!=EMPTY) i++;
//if i>=10 then all [] loaded
//if i<10 then [i]==EMPTY

Print(i);

.

my sudden doubt is this:
if condition is evaluated left to right completly without early exit - like what docs state for conditionals
then when i>=10 the condition: i<10 is false BUT the second condition ia[i]!=EMPTY will be executed
according to left to right complete conditional evaluation rule

One would expect that when eg, i is 10 then ia[10] should cause outOfBounds exception.

.

I have always been aware and coded around the lack of 'early exit' feature... in if's only.

.

for whatever reason, I never ever bothered with for and while conditional parts

and only when sorting out another issue when using loops, did it suddenly hit me that....

.

the above code runs 'as expected' and to prove that no early exit was going on when i was at 10,

a simple substitution of

&& ia[i]!=EMPTY

for

&& ia[i]!=v()

showed that v() called when i>=10

.

int v(){Print("v()");return(EMPTY);}
.

giving:

2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: 10
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()
2009.06.30 16:28:49 _quickySCRIPT_1 EURUSD,M30: v()

function call to print 'I was called' for the !=EMPTY

[Deleted]  

Your doubts are well founded. There is an order of precedence regarding evaluation of Boolean tests. You can consult the help guide for order of precedence, and calc things that way, but if ever you are in doubt, you can also group function tests (forcing your own precedence) with parenthesis.


Just as the statement a*b+c can be regarded as 5 * 10 = 50 + 10 = 60, or it can be seen as 5 * (10+10=20)= 100, Boolean evaluations can also leave questions of precedence.

But you can always force the issue with parenthesis rather than trust your own impeccable knowledge of MT4 precedence. You can at your own will say:

(5*10)+10 (actual precedence), or you can say 5*(10+10) (your own forced version).


So with Boolean the question is something like

if ( a==b && b==x || b>Y && c<d)

{

Do Something

}

else

{

Do Something else

}


This evaluation kind of hones in on the gist of it. Do I mean to evaluate as if((a==b && b==x) || (b>y && c<d)), or do I mean to ask: if(a==b && (b==x || b>y) && c<d) ?

Since these terms are very different in their evaluation, and result, then why not explicitly group them in accord to your desired result rather than rely on knowledge of inherent compiler precedence?

I think it best to group 'em according to your wishes using forcing parenthesis. It will be easier for you to read your code, and to review what you wrote. Your forcing parenthesis are like notations to yourself.

I don't care about precedence. I'm a creator of precedence... LOL...


However, there is a caveat regarding too many nested parenthesis. It really can get mind bogglingly complicated after about 4 levels of nesting. But my reply to this is just imagine not having the parenthesis as a guide, and trying to sort out the inherent precedence when it may not be flagged until the end of your code (if the compiler even catches it).