Multiplying INT and USUAL

This forum is meant for questions and discussions about the X# language and tools
Post Reply
boonnam
Posts: 88
Joined: Mon May 08, 2017 6:42 pm
Location: USA

Multiplying INT and USUAL

Post by boonnam »

Forgive me if this was brought up before. I did some search on this forum and could not find any mention of it. We are testing our conversion application from VO to X#. I ran into an interesting issue. Here is our line of code:

Code: Select all

iNoMode := IIF(m=4,2,1) * IIF( iPmtType = PAYMENT_REVERSAL, -1, 1 )
iNoMode and m are both INT type. iPmtType is a parameter. PAYMENT_REVERSAL is a define.
m=1
iPmtType=3
PAYMENT_REVERSAL=3

In VO iNoMode result is -1, but in X# it is 255. If I cast the factors as such:

Code: Select all

iNoMode := (INT)IIF(m=4,2,1) * (INT)IIF( iPmtType = PAYMENT_REVERSAL, -1, 1 )
Then the result is what we expected, which is -1. I am able to re-create this issue using console application.

Code: Select all

FUNCTION Start() AS VOID STRICT
    local iMode, iCount as int
    local iPmtType, iReversal as usual
    
    iPmtType := 3
    iReversal := 3
    iCount := 1
    
    iMode := iif(iCount==4,2,1) * iif(iPmtType == iReversal,-1,1)
    ? "iMode " + iMode:ToString()
   
    wait
    
    RETURN


I know it would be better if we strong type our variables. Is there is a plan to address this situation?

Thanks,
Boonnam
User avatar
robert
Posts: 4290
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Multiplying INT and USUAL

Post by robert »

Boonnam,
This is a tricky area.
We translate the IIF() statement to a C# conditional expression. In C# both results in the conditional expression must be of the same type. What we do in the X# compiler is determine what the (smallest) type of each the expressions is:
2 => unsigned byte
1 => unsigned byte
So the first IIF returns a byte
-1 -> Signed byte
1 -> unsigned Byte
So the second IIF returns a signed byte

Then you are multiplying an unsigned byte with a signed byte, So 2 different types.
For binary operations such as these we assume that the result of the multiplication is the type of the first operand when they both have the same size. Apparently in this case that is wrong.

I am afraid that this is deep in the hard of the compiler and changing this will most likely cause side effects.
Nevertheless: if does not hurt to add a ticket for this: https://github.com/X-Sharp/XSharpPublic/issues

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
Chris
Posts: 4599
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Multiplying INT and USUAL

Post by Chris »

Robert,

Can't you make relatively easily INT the smallest type that the compiler will assume for iif() expressions? And only if it is larger than that, then it may use an INT64/float etc. I am sure this will fix several similar issues which are probably hidden now.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
User avatar
robert
Posts: 4290
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Multiplying INT and USUAL

Post by robert »

Chris,
If I do that then assigning the result of an IIF() to a local of a type smaller than INT will cause problems, like in compiler test C652. Before I added the check for "smallest of the 2 operands" this was causing an error.

And the problem in this situation is not really the IIF() but the binary operation (multiplication) with 2 operands with different types that defaults to the type of the first operand

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
Chris
Posts: 4599
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Multiplying INT and USUAL

Post by Chris »

Robert,

I think it's better to make iif() return INTs and then require to enable /vo4 (implicit signed/unsigned conversions) for C652 to compile (in the VO/VFP etc dialects), instead of ever returning a byte form iif().

If you have existing VO code like:

LOCAL b AS BYTE
LOCAL n AS INT
b := n

then also in this case /vo4 is required, so I think this is the most natural way to workaround this.

Anyway, I will log this for now and include the info above.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
User avatar
ArneOrtlinghaus
Posts: 386
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Multiplying INT and USUAL

Post by ArneOrtlinghaus »

In the past we had many problems with IIF-pattern, that could be resolved expanding to normal if conditions. Sometimes It is nice to have short code, but often it is difficult to verify and as in this case having possible conversion problems.
Post Reply