xsharp.eu • Why has Goto(recordnumber) an INT?
Page 1 of 1

Why has Goto(recordnumber) an INT?

Posted: Thu Apr 01, 2021 5:02 pm
by ic2
One more issue I found when replacing Vulcan DLL's to X# DLL's in an X# project:

I always use DWORD for non negative numbers, as it was once recommended for VO.

Now I see for Goto in XSharp.RDD:
GoTo(nRec AS LONG)
nRec Type: Int32

Not sure if Int32 is the same as long, but why was Int32 chosen, which allow -2,147,483,648 to + 2,147,483,648? Why not DWORD (0 to 4,294,967,295.) - you can't go to a negative record anyway. (It was a usual in VO).

That's going to be a challenge for a future full conversion of all my VO code. I got many Goto(nRec) where nRec is a DWORD which I need to convert to Goto(Int(nRec)).....


Dick

Why has Goto(recordnumber) an INT?

Posted: Thu Apr 01, 2021 6:18 pm
by robert
Dick,

The USUAL value is the problem. Inside a USUAL value you store:
- Numbers < 2,147,483,648 as a LONG
- Numbers > 2,147,483,648 as a FLOAT
A DWORD is never stored "natively" inside a USUAL/
For this reason we have decided to make the variable for GoTo a LONG. That makes more sense.
Another reason is that the use of unsigned integers is not recommended in the Common Type System (CTS, see https://www.c-sharpcorner.com/UploadFil ... em-in-net/). We try to follow the rules of this in our code.

And really, no DBF in real life has a record count > 2 Gb. In fact even a file of 2 Gb bytes is not a good idea.

But I see no problems with the DWORD in your code, unless you code directly to the RDD layer.
DbGoto() and VoDbGoto() still have a USUAL parameter so the value will be converted from DWORD to LONG just like in
The Goto() method in the DbServer class also has a USUAL

The Signed integer is only in the RDD layer, which you normally do not code against, except when you write your own RDD.

Robert

Why has Goto(recordnumber) an INT?

Posted: Thu Apr 01, 2021 7:35 pm
by ic2
Hello Robert,
robert wrote:Dick,

But I see no problems with the DWORD in your code, unless you code directly to the RDD layer.
Thanks for the explanation. However I do get an error with this code, where nRecordnr is a DWORD:

oDBF:=DbServer{cDataPath+"tel.dbf",TRUE,FALSE}
lFound:=oDBF:GoTo(nRecordnr)


Error XS1503 Argument 1: cannot convert from 'dword' to 'int'

I would say I have this kind of code quite often and it is not coded directly on the RDD layer.

Dick

Why has Goto(recordnumber) an INT?

Posted: Thu Apr 01, 2021 8:26 pm
by robert
Dick,

What is the callstack for this error ?

Robert

Why has Goto(recordnumber) an INT?

Posted: Fri Apr 02, 2021 10:37 am
by ic2
Hello Robert,
robert wrote: What is the callstack for this error ?
The callstack??

It's a compiler error. It can be solved by changing it to lFound:=oDBF:GoTo(Int(nRecordnr))


Dick

Why has Goto(recordnumber) an INT?

Posted: Fri Apr 02, 2021 11:43 am
by robert
Dick,
ic2 wrote:Hello Robert,
Thanks for the explanation. However I do get an error with this code, where nRecordnr is a DWORD:

oDBF:=DbServer{cDataPath+"tel.dbf",TRUE,FALSE}
lFound:=oDBF:GoTo(nRecordnr)
Can you create an example. When I use the following code:

Code: Select all

FUNCTION Start( ) AS VOID
	LOCAL oServer AS DbServer
	LOCAL nRec AS DWORD
	oServer := DbServer{"c:cavo28SamplesGstutorcustomer.dbf"}
	nRec := 10
	? oServer:Goto(nRec)
	oServer:Close()
        WAIT
RETURN
in a project that has references to :
XSharp.Core.DLL
XSharp.VO.DLL
XSharp.RT.DLL
VOSystemClasses.DLL
VORDDClasses.DLL

And the compiler option:
/ins

then it compiles and runs without warnings.

So it must be something related to:
- Compiler Options
- References to other DLLs

Robert

Why has Goto(recordnumber) an INT?

Posted: Thu Apr 22, 2021 3:05 pm
by mainhatten
Hi Dick
ic2 wrote:I always use DWORD for non negative numbers, as it was once recommended for VO.
...
Not sure if Int32 is the same as long, but why was Int32 chosen, which allow -2,147,483,648 to + 2,147,483,648? Why not DWORD (0 to 4,294,967,295.) - you can't go to a negative record anyway. (It was a usual in VO).
a bit late and not really relevant for VO code: in vfp you can go to negative records - they mark new records in a table buffered alias. It may not read like a significant enhancement, but table buffering is a large part of the "secret sauce" of vfp: it isolates the persisted data from changes in GUI until a save action is asked for (and all validation coded is working). All new records added while not having called Tableupdate are not persisted to the base table or backend and therefore can be accessed via negative recno() starting with -1 up to -# of added records in the session currently in buffer.

When available in vfp dialect, try it - esp. if your GUI might handle multiple records to multiple tables and still need the option to throw away if customer is not interested ;-)

regards
thomas