• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Logical ops optimization bug

Status
Not open for further replies.
Level 19
Joined
Dec 12, 2010
Messages
2,069
What ya think will return
JASS:
return false and true or true
??
Jass says "false", because just as soon as it met "[false] and" statement without additional brackets it drops whole chunk (or at least it looks like this).

While in normal languages, including C++ and JS,
Code:
false && true || true
Code:
#include <stdio.h>

int main(void)
{
  if(0 && 1 || 1) printf("correct");
  else printf("bad");
}
equal to true

This behaviour is counter-intuitive and shouldn't exist

Test map attached. It's code:
JASS:
function asdasd takes nothing returns nothing
if false and true or true then
call BJDebugMsg("passed [false and true or true]")
else
call BJDebugMsg("[false and true or true] == false")
endif
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerAddAction(t,function asdasd)
    call TriggerRegisterTimerEvent(t,1,true)
endfunction
 

Attachments

  • LogicalOpsBug.w3x
    13.6 KB · Views: 72
I don't think that it is just dropping the latter half arbitrarily, but rather it is doing a different grouping. In JASS, it is:
return false and (true or true)
In C++, Python, etc. it is:
return (false and true) or true

This actually depends on the underlying grammar of JASS. But it is not necessarily a "bug". Both are valid interpretations.

Regardless, it is pretty interesting that JASS does this. But I don't think it warrants a fix: (1) because it is not an invalid interpretation (2) if (for some reason) some map relied on this precedence, it would break backwards compatibility. It might be cool to open a question on stack overflow about this though. I'm sure people who remember more about compilers will be able to give the technical details as to why it does this. Methinks it has to do with precedence or whether their boolean operators are left-associative vs. right-associative.
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
surely it may break some things, which has been done to follow this trick.
logical ops have no any value in terms of the order of equations (at least that what they said in schools). So it has to be read as "false and true or true", computing whole statement, instead of dropping it once "false and" construction happened.

As I showed, C++ (WC3 language) doesn't work that harsh, meaning it's not compile error, but jass' virtual machine issue. Since it's counter intuitive, it should be counted as a bug.

And, overall, it's not common knowledge, so there won't be many broken maps out of it. It's rather will fix some of them. Reminder - we aren't gonna change expressions like
JASS:
if (somefalsereturn() and SetUnitAbilityLevel(u,'abil',3)) then
, since there are only 2 ops in a row and this optimization make sense indeed.
 
DracoL1ch said:
logical ops have no any value in terms of the order of equations (at least that what they said in schools).

What do you mean?

DracoL1ch said:
As I showed, C++ (WC3 language) doesn't work that harsh, meaning it's not compile error, but jass' virtual machine issue. Since it's counter intuitive, it should be counted as a bug.

Yes, it is the VM. The reason I mentioned compilers is because the logic is the same--whether you're interpreting one line (e.g. JASS) or compiling a chunk of code, you still go through the phases of building a tree to determine the order in which expressions are evaluated. I agree that the order that JASS chose is counter intuitive, but as you said, it could break maps. Even if the number of those maps may be little to none, they assured us that that was one of their biggest priorities.
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
I mean engine shouldn't chose anything if expression doesn't contain brackets
a && b || c && d
One direction -> nothing to analyze more, just check every of given expressions
a && ((b||c) && d)
Ok, brackets require it to be parsed, so feel free to work from here.

sure, it's bad to break some maps, but again - it's not common sense and simply incorrect behaviour. programmers should't stick with that as well. anyway, Im using this subforum as a graveyard of few annoying/unclassified bugs I've met. If some of them aren't gonna be fixed it's fine, at least I told about them.
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
539
not a bug. when it comes to operator precedence everything but + - * / cannot be assumed to be known.
also when in doubt in your language design: do the opposite of what js and c++ do :alol:

But is this table correct?

It says and and or have the same precedence but (false and true or true) == ((false and true) or true) is as discussed false which means that they indeed have different precedence. (and they're both left-associative)

change your mind instead of force changing languages. it's way more rewarding.
 
Level 12
Joined
Mar 13, 2012
Messages
1,121
C++/Java and JASS both shortcut out of a boolean expression whenever possible.


C++/Java has a precedence of the "&&" over the "||" operator which generates subexpressions. If you don't understand what that means, as a simple example (containing no other operator with different precedence like "!") just imagine brackets surrounding every "&&" boolean expression.
false && true || true effectively becomes (false && true) || true,
true && false && false || true becomes ((true && false) && false) || true
and true || false && false becomes true || (false && false)


JASS has a precedence of the "or" over the "and" operator. Following the simple example, imagine brackets surrounding every "or" expression
false and true or true effectively becomes false and (true or true),
true and false and false or true becomes true and false and (false or true)
and true or false and false becomes (true or false) and false

One can create additional subexpressions with brackets, "==", "!=" and "not".



It's dangerous to change this ~15 years after release(, else I would take it in the list). If you want a different order of evaluation use brackets.
 
Last edited:
Level 12
Joined
Mar 13, 2012
Messages
1,121
*cough cough* damn that happens when you're in a hurry.

It seems that in JASS actually the "or" operator has precedence over the "and" operator.

true or false and false evaluates to false.


tt... Now that I mention this, I think I already tested that once.. edited the upper post
 
Last edited:
Level 2
Joined
Feb 15, 2016
Messages
9
I thought it was a pretty widely accepted notion that AND operators take precedence over OR. Most languages I've seen prioritize AND over OR in boolean expressions. This is odd, but like Purge said, since this can break compatibility, it should be left as it is, most likely.
 
Status
Not open for further replies.
Top