And again the old song about REF and NULL

Public support forum for peer to peer support with related to the Visual Objects and Vulcan.NET products
leon-ts
Posts: 429
Joined: Fri Feb 03, 2017 1:43 pm

And again the old song about REF and NULL

Post by leon-ts »

Hello,

Some time ago, the question of a special syntax was discussed, in which VO and Vulcan pass NULL to parameters of functions/methods that accept reference values ​​(REF).

Sample (abstract):

FUNCTION Func1(x AS INT, y AS INT, z REF INT) AS INT

IF (@z) != NULL
z := x * y
ENDIF

RETURN x + y

// Using
SumVal1 := Func1(2, 5, NULL)
SumVal2 := Func1(3, 8, @MultVal)


Vulcan supports this syntax when you include the /vo7 (Compatible Implicit Casts And Conversions) parameter in the project properties.

When can XSharp be expected to support this feature?

After all, it can be maintained virtually in a language. For example, in the process of compiling code in such places, instead of NULL substitute references to real variables (internal, created by the compiler). Or implement this approach even at the stage of code conversion in XPorter.

Now there are two big problems that prevent my enterprise moving from VO to .NET (XSharp). This is the problem described above and the lack of MEMVAR support. The amount of code is huge, it began as early as 1993 and underwent a change from Clipper (DOS) to VO 2.5/2.7/2.8SP3 (Windows). Now 15 programmers work on the project. We need maximum support in XSharp syntax of VO.

Best regards,
Leonid
Best regards,
Leonid
User avatar
robert
Posts: 4225
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

And again the old song about REF and NULL

Post by robert »

Leonid,

In VO you can mix REF variables and typed pointers. However these are quit different.
REF variables can never be NULL, typed pointers can.

Vulcan introduced the /vo7 compiler switch. We support that too. This switch allows you to use the typed pointer syntax for reference variables.

An example of a typed pointer

Code: Select all

FUNCTION Func2(x AS INT, y AS INT, z AS INT PTR) AS INT 
IF z != NULL
   z[1] := x * y
ENDIF

RETURN x + y
Finally: MEMVAR support is planned for the X# runtime that we are currently working on.
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
Chris
Posts: 4562
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

And again the old song about REF and NULL

Post by Chris »

Leonid, Robert,

Had we discussed before that Vulcan does allow even NULL to be passed to REF params? Just like Robert, I thought this is not possible at all, but to my surprise it turns out that it actually is possible, looks like a hack Don had added at some point. We will have a look to see if/how this can be done in x# too and will get back to you. Of course everything else in Robert's post is true, too.

Chris
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
leon-ts
Posts: 429
Joined: Fri Feb 03, 2017 1:43 pm

And again the old song about REF and NULL

Post by leon-ts »

Robert, Chris,
Thank you for reply
However these are quit different.
REF variables can never be NULL, typed pointers can.
But nevertheless VO it supports. I can pass NULL and this will work. This is especially true for variables of type STRING. If the parameter is described as AS STRING PTR, communication with GC is lost. In the case of REF, this problem does not occur.

I understand that this behavior in XSharp is somehow related to the limitations of C # (REF and OUT). Therefore, I suggested, can make the necessary replacement in the code at the stage of project import through XPorter?

Sample

Code: Select all

FUNCTION f1(x REF STRING) AS VOID
RETURN
It was:

Code: Select all

f1(@c)
f1(NULL)
Became:

Code: Select all

f1(@c)
LOCAL __null_ref_to_string AS STRING // generated by XPorter
f1(@__null_ref_to_string)
Vulcan introduced the /vo7 compiler switch. We support that too. This switch allows you to use the typed pointer syntax for reference variables.
This I found experimentally. If Vulcan turns off / vo7, the compiler starts to swear by NULL in the REF. If this option is enabled, NULL is allowed and still works correctly (as in VO). Enabling this option in XSharp does not have the same effect.
Had we discussed before that Vulcan does allow even NULL to be passed to REF params?
We did not mention Vulcan last time. Now I drew attention to this only because if in Vulcan a solution for this nuance was found, then it is possible to do this in XSharp.
Best regards,
Leonid
User avatar
Chris
Posts: 4562
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

And again the old song about REF and NULL

Post by Chris »

Hi Leonid,

I think this is a big hack done in the vulcan compiler that allows this, I am almost sure that if you test the produced exe/dll containing this compiled code against PEVerify (which checks integrity of .Net code), it will produce all sorts of errors.

But the fact is that it does work, so we'll look into implementing it in x# as well. Vulcan just generates any IL code it wants, while in X# it will be much more difficult to do that, as x# uses the c# backend, which definitely does not allow something like that. But maybe Robert will find a backdoor, will discuss it and will let you know.

If that fails, we will look into implementing what you suggested in VOXporter.

Chris
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
leon-ts
Posts: 429
Joined: Fri Feb 03, 2017 1:43 pm

And again the old song about REF and NULL

Post by leon-ts »

Chris, thank you!
I really hope that some of the solutions will be found.

Best regards,
Leonid
Best regards,
Leonid
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

And again the old song about REF and NULL

Post by wriedmann »

Hi Chris,
If that fails, we will look into implementing what you suggested in VOXporter.
my personal opinion (as I have tons of VO code too):
Please implement that in the XPorter and don't hack the X# compiler.
Then the compiler can check the code and it can eventually been fixed, and it does not leed to problems later at runtime.
IMHO code will be more stable when the XPorter changes the code....

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
robert
Posts: 4225
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

And again the old song about REF and NULL

Post by robert »

Chris,
Chris Pyrgas wrote:
But the fact is that it does work, so we'll look into implementing it in x# as well. Vulcan just generates any IL code it wants, while in X# it will be much more difficult to do that, as x# uses the c# backend, which definitely does not allow something like that. But maybe Robert will find a backdoor, will discuss it and will let you know.
It will not be easy to do this in the compiler.
I have seen some samples that do this, but in that case the function declaration of the function that expects the ref has to be changed.

Another alternative would be to generate a temporary local by the compiler and pass that to the function in stead of the NULL argument. In that case the NULL check inside the function will never be true, since the compiler will then make sure that the reference is valid.


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

And again the old song about REF and NULL

Post by Chris »

Robert,
Robert van der Hulst wrote: Another alternative would be to generate a temporary local by the compiler and pass that to the function in stead of the NULL argument. In that case the NULL check inside the function will never be true, since the compiler will then make sure that the reference is valid.
Ah, right, so for the same reason this can't be done in the VOXporter, either, as the proposed change would work for reference types only (as they can be NULL), but not for value types. So this either needs to be implemented in the compiler somehow, or the code must be changed.

Unless it can be implemented with Nullable types? Just thinking aloud here..

Chris
Chris Pyrgas

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

And again the old song about REF and NULL

Post by robert »

Leonid,

Code: Select all

FUNCTION Func1(x AS INT, y AS INT, z REF INT) AS INT
    IF (@z) != NULL
        z := x * y
    ENDIF
RETURN x + y
Even in VO this is considered "dirty" syntax. You can only get this to compile when you surround the @z with parentheses like in your example.

If you try it like this:

Code: Select all

FUNCTION Func1(x AS INT, y AS INT, z REF INT) AS INT
    IF @z != NULL
        z := x * y
    ENDIF
RETURN x + y
Then VO will report "bad @ expression".
Having said that: I have implemented a quick fix in the compiler today. Chris will test it and if he sees no side effects then this will be part of the next build.


Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Post Reply