[Gambas-user] Minor bug with READ & WRITE commands?
Benoit Minisini
gambas at ...1...
Mon Jan 19 02:01:51 CET 2009
On vendredi 16 janvier 2009, nando wrote:
> Benoit,
>
> Question regarding the line:
> > > WRITE #pResult + (ii * 8), .x
>
> does WRITE see it casted as variant or int ?
> -Fernando
>
You exactly got the point. :-)
As fResult is an Object[] array, fResult[ii].x is a Variant.
Why? Because, in Gambas, the datatype of an operator or a function is never
more precise than the datatype of the arguments, unless the operator or
function always returns the same datatype. Read that sentence at least twice.
So, as fResult is Object[], then fResult[ii] is Object, and fResult[ii].x is
always a Variant, as the interpreter cannot know that fResult[ii] is always a
Class1.
As READ and WRITE receive a Variant, they read/write a byte before the value
in memory.
So what is written at the pointer is not two bytes &H64+&H00 (the 100 value)
but three bytes &H04+&H64+&H00 (&H04 meaning Integer).
As the memory address is computed at each loop, the third byte is replaced by
the first byte of the next write. The last written byte is outside of the
array. It does not crash because memory allocation are often rounded by the C
library.
When reading, what happens? The GetAStruct C function receives:
&H04+&H64+ &H04+&HC8+ &H04+&H64 +...+ &H04+&HC8+&H00
And modifies it:
&H0E+&H64+ &H05+&HC8+ ...
Then READ wants to read a Variant, and so interprets the first byte, &H0E, as
a datatype that means...a Class, something that is cannot understand, and so
you get an error message. But in other situations, you can crash the
interpreter, because READ can write in memory more than expected!
What is the solution? You have to tell Gambas which is the real datatype to
read and write.
The first solutiion is what you did: using a local variable with the accurate
datatype.
The second solution is not having Object as intermediate expression datatype.
Instead of:
WITH fResult[ii]
Do that:
DIM hClass AS Class1
hClass = fResult[ii]
WITH hClass
Then the interpreter will know at runtime that hClass is a Class1, and so that
hClass.x is always an integer.
So, all that is not really a bug, but I admit it is a bit weird, and not
beginner-friendly.
In Gambas 3, I'm currently thinking about a better, or at least clearer
syntax. It will be a mix of:
- True memory streams, i.e. a class that inherits Stream and that points at a
memory emplacement.
- Classic Basic memory access function. PEEK, POKE ? :-) And/Or MkInt$(),
MkLong$()...
- Explicitely specifying the datatype in READ and/or WRITE, or having
ReadInteger(), ReadFloat(), WriteInteger()... methods in the Stream class, or
as subroutines.
People, tell me what you think about that. I'm going to bed now.
--
Benoit Minisini
More information about the User
mailing list