Bugs revealed by X# in existing code - part 1

As we announced a couple weeks ago, we have recently (to be precise, that was in Athens, at 20:56 of December 29th, 2016  smile achieved a major milestone for X#: Now the compiler can successfully compile all *valid* existing Vulcan code, or at least all existing code that we have tested the compiler with. And thanks to many of you who have provided us literally many 100s of thousands of lines of your code for our testing, we have tested the compiler against A LOT of existing code!

Of course we have tested the compiler also with our own code, like the source code for XIDE for example, which was previously written in Vulcan and even tested it with existing VO code that has not been ported to Vulcan at all. In the process, the stricter and more powerful X# compiler has revealed several problems in existing code (in the VO SDK, in the Vulcan version of the SDK, in ours and in other developers’ code), some of which should have never been allowed to compile before at all.
We have collected a of such problems, and we want to present them to you so you can learn from it

Assignment made to the same variable

This is by far the most common issue in existing code revealed by the X# compiler. Here is a simple case:

FUNCTION Absolute(nValue AS INT) AS INT
LOCAL
nRetValue AS INT
IF
nValue > 0
     nValue := nValue // typo, should be nRetValue := nValue
ELSE
     nRetValue := - nValue
END IF
RETURN
nRetValue

VO and Vulcan do not report an error or warning on this, while X# does report a warning: warning XS1717: Assignment made to same variable; did you mean to assign something else?

This may look like a very obvious typo that one could think is nearly impossible to miss, but in reality it occurs very often and I was very surprised on how many times X# found this in my old code, helping me to fix several related bugs in XIDE! I’d suggest that you also try to compile your applications with X# and see if the compiler finds such cases in your code as well. Warning: don’t be quick to predict that there will be none!

Note that sometimes such a code construct is used by some developers on purpose, to suggest that no action needs to be taken indeed, like in the code below, where it is used to prevent the compiler warning about an empty CASE block:

DO CASE
CASE lCopyFromOther
     nMyValue := nOtherValue
CASE lLeaveItAlone
     nMyValue := nMyValue // no action needs to be taken
CASE lMakeItZero
     nMyValue := 0
END CASE

For cases like this, we have introduced the NOP (No OPeration) command in X#, which makes such code clearer to read and avoids reporting this warning:

DO CASE
CASE
lCopyFromOther

     nMyValue := nOtherValue
CASE lLeaveItAlone
     NOP // no action needs to be taken
CASE lMakeItZero

     nMyValue := 0
END CASE

Comparing object to string

This is something else that we found in a few places in existing Vulcan code (not in VO code, as VO does report an error on this):

METHOD ValidateValues() AS LOGIC
// typo, that should be SELF:oDCMySLE:TextValue
IF SELF:oDCMySLE == ""
     RETURN FALSE
END
IF
RETURN
TRUE

Vulcan does not report any error or warning about this, and because of course the comparison between SELF:oDCMySLE (instance of the SingleLineEdit class) and an empty string will always be false, this method was always returning TRUE at runtime when compiled in Vulcan, resulting to incorrect runtime behavior. On the other hand, when compiling this in X#, the compiler reports an error: Operator '==' cannot be applied to operands of type 'SingleLineEdit' and 'string' which makes us realize that there is a typo in the code and we will now change the comparison to

IF SELF:oDCMySLE:TextValue == ""

which works as it was originally intended to at runtime.

This concludes our article for today.


Next week we will continue with part 2 of this topic in which we will have a look at assignments and binary operators.

No comments