MQL5 fails a simple boolean test? If(false) then do it, but it's true, do it anyway?

 

Never seen the like. I have a simple test for a boolean value...


//      

   bDoDirPvt                              = false;
   iPvtTrdIX                              = -1;
   
   if(bIs1stPsn == false)
   {
      if(iTrdIX > 0)
         bDoDirPvt                        = (iaTrdDir[iTrdIX-1] != iaTrdDir[iTrdIX])   ? true : false;
   }
//

I put a breakpoint on the if(bIs1stPsn == false) statement and click the green "play" button in the IDE toolbar:

Tester stops there fine. You can see that bIs1stPsn == false (in the debug tab) , so the if statement should evaluate to false, and the next two lines of code should not execute.

So, I hit F10 to execute the line, and where does the tester end up?


Right inside the if structure it was excluded from, because bIs1stPsn == true, not false, as you can see. So, execution should go to the else branch, skipping the next two lines.

The if should have evaluated to false and skipped the code inside the if structure. 

Or am I about to facepalm again because I'm overlooking something obvious?

 

Print the value of a variable to a log

   bDoDirPvt                              = false;
   iPvtTrdIX                              = -1;
   Print("bIs1stPsn = ", bIs1stPsn);
   if(bIs1stPsn == false)

What will be in the journal?

 
  1. Your code
     bDoDirPvt                        = (iaTrdDir[iTrdIX-1] != iaTrdDir[iTrdIX])   ? true : false;
    Simplified
     bDoDirPvt                        = iaTrdDir[iTrdIX-1] != iaTrdDir[iTrdIX];
  2. Doubles are rarely equal. Understand the links in:
              The == operand. - MQL4 programming forum #2 (2013)

  3. Are you accessing your array as non-series?

 
Is the variable bIs1stPsn declared only once in your code? I mean, if there is two variables with the same name, one declared in the local scope and the other on the global scope, the one in the local scope is actually used for that function purpose. That may be one reason why this is happening. Otherwise, this is probably (not certainly) some other error within your code, not in the compiler. Not easy to detect it though without the source or some executable piece of code that reproduces the error.
 
William Roeder #:
  1. Your code
    Simplified
  2. Doubles are rarely equal. Understand the links in:
              The == operand. - MQL4 programming forum #2 (2013)

  3. Are you accessing your array as non-series?

Those aren't doubles. I use a naming convention: variable names starting with "b" are boolean, integers are "i". If they were doubles, their names would start with "d".

The problem has nothing to do with the line you simplified, though -- although I like the way you did that.

The problem is solely with "if(bIs1stPsn == false)" which effectively compiles into " if(bIs1stPsn == true).

That's a big problem, because it's a 180 degree, wrong as it could be blooper and the most fundamental level, logically. False does not mean true.

 
Vladislav Boyko #:

Print the value of a variable to a log

What will be in the journal?

You think that the debug real-time display as shown in the screenshots are going to say differently than if I printed the value to the Experts tab? I often do print to that for debugging purposes. I could try, but that's a Catch-22, too. If the debugger shows one value and Print() reveals a different value, that's just makes a 2nd problem with the compiler, the debugger, or both. 

 
Emanuel Cavalcante Amorim Filho #:
Is the variable bIs1stPsn declared only once in your code? I mean, if there is two variables with the same name, one declared in the local scope and the other on the global scope, the one in the local scope is actually used for that function purpose. That may be one reason why this is happening. Otherwise, this is probably (not certainly) some other error within your code, not in the compiler. Not easy to detect it though without the source or some executable piece of code that reproduces the error.

b1stPsn is a bool declared in global space, accessible everywhere throughout the code. Only one name/variable in the file by that name. But even if there was a local one, the local variable would preempt the global variable and the compiler notes it. I make sure I get squeaky-clean compiles. So, no.

Either way, local or global, I'm looking at "true" in the variable at the time the code hits the breakpoint. The debugger is showing the value of the b1stPsn you're looking at. But I'll double-check and absolutely rule out the possibility that the value shown does not reflect the value at the time those screenshots were taken, which was as the code you see was executing.

 
Millard Melnyk #:

You think that the debug real-time display as shown in the screenshots are going to say differently than if I printed the value to the Experts tab? I often do print to that for debugging purposes. I could try, but that's a Catch-22, too. If the debugger shows one value and Print() reveals a different value, that's just makes a 2nd problem with the compiler, the debugger, or both. 

I have little experience with the debugger, so I don't know all the nuances of working with it. But if you add Print() in the place that I showed, it will 100% show the value of the variable. This will speed up progress in identifying the problem.

 
Vladislav Boyko #:

I have little experience with the debugger, so I don't know all the nuances of working with it. But if you add Print() in the place that I showed, it will 100% show the value of the variable. This will speed up progress in identifying the problem.

I did as you suggested and satisfied myself that the problem lies with the debugger, the little bugger, lol.

So I put a Print right before the "if(bIs1stPsn == false)" line, and another right before the "if(iTrdIX > 0)" line. On the OnCalculate cycle where  bIs1stPsn == true, the Print and the debugger both show the same value for bIs1stPsn: true.

And here comes the catch: When the Print statements are active, code execution proceeds as you'd expect. Code inside the if structure is bypassed when bIs1stPsn == true and executed when it's false, just as it should. The patient only shows symptoms when the doctor's not looking! 😆

Then, after I've commented out both Print statements, execution reverts right back to executing the code inside the if structure, regardless... according to the debugger. Maybe it's got something to do with having 2 if structures adjacent. I put a dummy "int ii = 0;" statement right before the "if(iTrdIX > 0)" line, and then the debugger gets "if(bIs1stPsn == false)" right.

So, although I've no idea why the debugger glitches like this, at least my faith in the compiler has been restored.

Thank you!

 
I tried to reproduce the bug but i can't (it worked fine)
void OnStart() {
  bool x = false;
  if(x == false) {
    Print(false);
  }
  if(x == true) {
    Print(true);
  }
}
Can you post the simplify version of your code?
 
Le Minh Duc #:
  if(x == false) {
⋮
  if(x == true) {

You should be able to read your code out loud and have it make sense. You would never write if( (2+2 == 4) == true) would you? if(2+2 == 4) is sufficient. So don't write if(bool == true), just use if(bool) or if(!bool). Code becomes self documenting when you use meaningful variable names, like bool isLongEnabled where as Long_Entry sounds like a trigger price or a ticket number and “if long entry” is an incomplete sentence.