If something like.. WRITE #pResult + (ii * 8), CINT(.x) casts it as int, then no problem
---------- Original Message ----------- From: Benoit Minisini <gam...@users.sourceforge.net> To: nand...@nothingsimple.com, mailing list for gambas users <gambas-user@lists.sourceforge.net> Sent: Mon, 19 Jan 2009 02:01:51 +0100 Subject: Re: [Gambas-user] Minor bug with READ & WRITE commands? > 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 > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by: > SourcForge Community > SourceForge wants to tell your story. > http://p.sf.net/sfu/sf-spreadtheword > _______________________________________________ > Gambas-user mailing list > Gambas-user@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/gambas-user ------- End of Original Message ------- ------------------------------------------------------------------------------ This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword _______________________________________________ Gambas-user mailing list Gambas-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gambas-user