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