Recent

Author Topic: It seems that If statement needs ( and ) to be reliable  (Read 3779 times)

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
It seems that If statement needs ( and ) to be reliable
« on: March 21, 2018, 10:47:34 pm »
I've run into this for many years.  If you are using an "if" statement to compare two integers, the compare will seem to always resolve to false if the first variable is zero, and it will resolve to true, if the first variable is 1.  All other numbers work correctly.

I've had to debug this so many times, I've started to put unnecessary parenthesis in my "if" statements, as if they are part of the key word list.  Example:

if recno < reccount then
  ...

I always write as:

if (recno < reccount) then
  ...

If recno happens to be 1, then it pops out of the IF, even if reccount is greater than one!

I have not changed any compiler defaults  (like "give up as soon as you hit a true variable", and 1 = True)... (I don't even know where that is in Lazarus.  Or... maybe this is the default setting and I'm supposed to go in and change it so the compiler evaluates right to the end.

Platform:   Lazarus 1.8.1, FPC 3.0.5

I had this happen in Delphi all the time too. 





Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: It seems that If statement needs ( and ) to be reliable
« Reply #1 on: March 21, 2018, 11:00:38 pm »
I beg to differ:

Code: Pascal  [Select][+][-]
  1. begin
  2.   writeln('0 <  2 = ',0 < 2);
  3.   writeln('0 < -2 = ',0 < -2);
  4.   writeln('1 <  2 = ',1 < 2);
  5.   writeln('1 < -2 = ',1 < -2);
  6. end.
  7.  

Ouputs:
Code: [Select]
0 <  2 = TRUE
0 < -2 = FALSE
1 <  2 = TRUE
1 < -2 = FALSE

This is as it has always been and always will be.

Do you truly believe that a compiler, at version 3.0.4, is as stupid as not to be able to compare integers, and that nobody else but you ever noticed that?
Really?
Really, really, really?????

WTF?

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6077
Re: It seems that If statement needs ( and ) to be reliable
« Reply #2 on: March 22, 2018, 01:00:51 am »
he most likely is not providing the full example that fails..

 I suspect that maybe he has more compound statements using functions that do not get executed if
 previous statement fails the test, "Short circuit" evaluation..

  If such functionality is required then a compiler switch is needed at the section where he needs this to happen.
The only true wisdom is knowing you know nothing

GAN

  • Sr. Member
  • ****
  • Posts: 370
Lazarus 2.0.8 FPC 3.0.4 Linux Mint Mate 19.3
Zeos 7̶.̶2̶.̶6̶ 7.1.3a-stable - Sqlite 3.32.3 - LazReport

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: It seems that If statement needs ( and ) to be reliable
« Reply #4 on: March 22, 2018, 04:06:26 am »
Guys, this is the problem...

"if" accepts (or rejects) when it shd not.  It is the only single condition.  There is nothing else going on in the "if".  I put parenthesis around the single condition and it suddenly works.  If I make a very simple sample project (which I have done), it works correctly, with or without parenthesis.  So I'm wondering if there is code above that point that is somehow affecting the operation of a simple 'if'.  I cannot include the complete unit code as it is proprietary.

If I can somehow narrow down what is going on, I will provide more info.  Delphi had this same thing going on.  I wd waste a lot of time debugging a problem, and avoiding putting parenthesis around such a simple condition in an "if", however, I would relent, try the parenthesis in and boom!  It works. 

I have seen this happen occasionally (rarely) for many years.

Having said all that, is there a compiler switch in Lazarus that tells the compiler to enforce evaluation all the way to the end of all the conditions, instead of just "accepting" the first "true" resolution?

"if" shd not require parenthesis for one single simple condition.  I know that.  But occasionally, it doesn't work that way.

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: It seems that If statement needs ( and ) to be reliable
« Reply #5 on: March 22, 2018, 04:08:06 am »
Also.. I want something to happen on every iteration except the last one.  So

recno < reccount

is correct.

ASerge

  • Hero Member
  • *****
  • Posts: 2212
Re: It seems that If statement needs ( and ) to be reliable
« Reply #6 on: March 22, 2018, 06:48:40 am »
Having said all that, is there a compiler switch in Lazarus that tells the compiler to enforce evaluation all the way to the end of all the conditions, instead of just "accepting" the first "true" resolution?
{$BOOLEVAL ON}
Quote
But occasionally, it doesn't work that way.
I do not believe.

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: It seems that If statement needs ( and ) to be reliable
« Reply #7 on: March 22, 2018, 02:36:40 pm »
The common thread is that, considering the variables from left to right... the first one is always an integer variable, and it contains a zero or a one.  Every other number works reliably without ( and ). Anyways... BOLO.

(Be On The Look Out)

Thaddy

  • Hero Member
  • *****
  • Posts: 14157
  • Probably until I exterminate Putin.
Re: It seems that If statement needs ( and ) to be reliable
« Reply #8 on: March 22, 2018, 04:06:40 pm »
The common thread is that, considering the variables from left to right... the first one is always an integer variable, and it contains a zero or a one.  Every other number works reliably without ( and ). Anyways... BOLO.

(Be On The Look Out)
Well, The type of variable does not matter. It is the first boolean expression that fails the predicate/assumption.
And we still have NO code....ASerge is right: the compiler does not make mistakes with Boolean evaluation (either shortcut or full). If you think it does, you really need to provide code.
Let me guess: you can't.
Specialize a type, not a var.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9754
  • Debugger - SynEdit - and more
    • wiki
Re: It seems that If statement needs ( and ) to be reliable
« Reply #9 on: March 22, 2018, 04:18:13 pm »
if recno < reccount then

Are they both "integer" ? (not byte, not word, not ....) // I dont think it matters, but lets be exact.

Do you have overloaded operators? (Or maybe they are in some unit where you do not expect them?

Have you looked at the generated assembler? Project options > Custom Options > add: -al

Compare the assembler for with/without brackets.
Compare the assembler with what the debugger shows, if you ask the debugger to disassemble.

-----------
Does it happen at any optimization level? Even "no optimization"?

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: It seems that If statement needs ( and ) to be reliable
« Reply #10 on: March 22, 2018, 04:22:23 pm »
All good followup info gentleman.  Thanks.  I will take a closer look once this happens again, based on your input.

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: It seems that If statement needs ( and ) to be reliable
« Reply #11 on: March 22, 2018, 04:29:11 pm »
I understand for certain reasons, sometimes we're not willing/allowed to publicize the code. You can remove all the unnecessary things, leaving the compilable/runable part that can cause the issue. Bug in if-statement is a serious issue, we really very eager to help you solve it.

RedOctober

  • Sr. Member
  • ****
  • Posts: 450
Re: It seems that If statement needs ( and ) to be reliable
« Reply #12 on: March 22, 2018, 04:57:43 pm »
Hi Everyone.  I'm not reporting this as a bug.  This happened in Delphi also.
Now that you all got me thinking about this, I remember there were two occasions when this problem happened (in Delphi) (in the distant past, in different versions of Delphi) where instead of using the ( and ) around the IF condition(s), I simply added a self negating line of code above where the IF statement was.  Example:

Code: Pascal  [Select][+][-]
  1. a := a;
  2.  

This forced the following code (where the IF statement was) to be bumped down one line, re-line numbered and the compiler then worked correctly and the IF worked correctly, even without parenthesis.

It's as if a section of source code was resulting in a misinterpreted assembler section, and bumping everything down one line forced a new section of assembler to be created and fixed.

This is wacky, I know.  But it happened.  It's so crazy that it's not recreatable without the entire suspect source code.  Leave it with me for now.  I posted originally, just to see if anyone else had experienced this over the years they've been doing this.

From your responses, the answer is "no".  So leave it with me for now.  I will re-train myself to stop using unnecessary ( and ) based on your answers.


« Last Edit: March 22, 2018, 05:10:12 pm by RedOctober »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9754
  • Debugger - SynEdit - and more
    • wiki
Re: It seems that If statement needs ( and ) to be reliable
« Reply #13 on: March 22, 2018, 05:50:26 pm »
I simply added a self negating line of code above where the IF statement was.  Example:
Code: Pascal  [Select][+][-]
  1. a := a;
  2.  

As strange as it is (and stranger so, that 2 independent compilers do the same in this case)

This line could throw the optimizer off, and prevent it from doing something that may not be expected (or that you do not expect)

If that line generates code, it also affects the peephole optimizer.

Quote
From your responses, the answer is "no".  So leave it with me for now.  I will re-train myself to stop using unnecessary ( and ) based on your answers.

If it happens again, please compare the 3 assembler outputs.

« Last Edit: March 22, 2018, 05:52:46 pm by Martin_fr »

 

TinyPortal © 2005-2018