Strange behavior inverting an integer


during debugging, I just came across a quite strange behavior of operator precedence with integers and booleans. Please have a look to the following code detailing my findings:

[code] dim v as Variant
v = 3

system.DebugLog "v = " + str(v) //prints 3
system.DebugLog "v.type = " + str(v.Type) //prints 2
System.DebugLog "variant.typeobject = " + str(Variant.TypeObject) //prints 9

if not v.Type = Variant.TypeObject then
Break //breaks here - that’s not expected at the first glance…
end if

if v.Type <> Variant.TypeObject then
Break //breaks here. ok that works, but shouldn’t this be equivalent?
end if

if not (v.Type = Variant.TypeObject) then
Break //breaks here, that’s ok, again
end if

if (not v.Type) = Variant.TypeObject then
Break //breaks here. as in first test. so it seems it is doing that instead.
end if

//obviously the not has a higher precedence then the =, which is fine for booleans
//but variant.type is an integer, can that be negated?

dim i as integer
dim b as Boolean
'b = not i //no, that won’t compile…

//maybe that’s because Variant.Type is a Method, try this:
'b = not func() //not, won’t compile either…

system.DebugLog "not(v.type) = " + str(not(v.Type)) //prints -3 //very stange, would expect -2 at best.

//this explains why the original if-statement is behaveing as it is,
//but still - why can I invert this expression v.type at all?

Can anybody explain what is happening here? any implicit type conversion or operator_convert I’m not aware of?


There was a discussion about this on here the other day.

If you do this:

  system.DebugLog "v.type = " + str(not v.Type)  

you’ll find it prints -3. I’m not sure why RS defines the inverse of 2 as -3; ‘not 2’ could be defined as 1, or 0, or -2, or 23465236.

Personally I only ever use ‘not’ after ‘if’ when I’m referring to booleans, because there are obviously only two values they can be (i.e. True or False).

Instead, I always use a vanilla If statement with <> like in your second test.

I believe I had the same problem a few days ago. Massimo Valle made a topic about it:

Instead of writing things like if not i = 20 then write it like if i <> 20 then or use brackets: if not (i = 20) then

It took me a good hour or so to work this logic error out of my code.

thanks @Joshua Woods for pointing me to @Massimo Valle 's thread. Shame on me for not searching first.

The thing that I overlooked was that NOT is not only a boolean operator but also an bitwise one. So given the following

dim i as integer = 5 dim j as integer dim b as boolean
the boolean operator would not work: b = not i but the bitwise would: j = not i
that explains the case as NOT has (and should have!) a higher precedence then =
Consequently even in a pure boolean expression not a = b this is not interpreted as not (a=b) but (not a) = b. If there wouldn’t be the bitwise operator implemented with the same name, my not integer = integer expression would have given a compilation error, not the term not(integer = integer) as I wrongly assumed in the first place. I knew it but was lead from a wrong assumption.

Use the brackets, dude :wink:

NOT has higher precedence than = so you have effective got

 if (not v.Type) = Variant.TypeObject then

when what you want is

 if not (v.Type = Variant.TypeObject) then

Not has both a logical and bitwise version
You’re getting the bitwise one applied first then the comparison

When in doubt bracket