shifters74 wrote: ↑Wed Jul 06, 2022 2:04 pm
Code: Select all
res[t_session] sessions[MAX_NUMBER_SESSIONS + 1]
How would you then access each structure e.g. sessions[1].stationid = 1 to set stationid in structure 1 etc, and recall it as puti(sessions[1].stationid)
I have tried the above but I am getting corrupt data when i read all the structures back.
Hi shifters,
Good question! I have had a play with this and I think that although the definition works like this to allocate space, the compiler does *not* "remember" that the elements of sessions are t_session bytes long; it is just a simple byte array as far as any subsequent code is concerned. So you need to use "n * t_session" as the array index, not just "n". I could be wrong here, but that's how it looks to me like it works. This is a bit of a shame, and coming from a C background it's definitely a gotcha, but my best guess is this is done to keep the compiler simple.
For what it's worth, I investigated this by looking at the bytecode generated by the compiler (using -O, as it was easier to interpret after optimisation). The initial loop assigning the 0 values does:
Code: Select all
; <stdin>: 0020: // clear each of the structures
; <stdin>: 0021: for index = 0 to MAX_NUMBER_SESSIONS
_SUBSEG ; BYTECODE STARTS
_INIT
!BYTE $14 ; CN 10
!BYTE $00 ; CN 0
_B002
!BYTE $7C ; DAB _D029+0
_F000 !WORD _D029+0
; <stdin>: 0022: // set the session structure details
; <stdin>: 0023: sessions[index].stationid = 0
; <stdin>: 0024: sessions[index].state = 0
; <stdin>: 0025: sessions[index].avatarid = 0
; <stdin>: 0026: next
!BYTE $00 ; CN 0
!BYTE $26 ; LA _D028+0
_F001 !WORD _D028+0
!BYTE $B4 ; ADDAB _D029+0
_F002 !WORD _D029+0
!BYTE $70 ; SB
_D028 is the 44 byte "sessions" array and _D029 is the loop index. "LA _D028+0" puts the address of _D028 on the stack and "ADDAB _D029+0" adds the byte value at _D029 to the value on the stack. "SB" then stores the 0 pushed earlier by "CN 0" as a byte at the address on top of stack. So we're using the raw value at _D029 as the offset from _D028 without multiplying it by t_session.
I'm 99% sure this analysis is correct and shows *why* your code isn't doing what we'd expect it to, but this doesn't say anything about whether by tweaking the source code slightly the compiler would start doing the multiplication by the element size automatically. Looking quickly at the compiler source code,
in toolsrc/parse.c, parse_struc() seems to be the code which parses these definitions - note that "res" is just a synonym for "byte", so we will have a BYTE_TOKEN when parsing this. The code recognises the open brackets and sets basesize and size and subsequently multiplies size by basesize, but it doesn't appear to store size/basesize anywhere for future reference when indexing. Oops, that's wrong - it's almost certainly in the BYTE_TOKEN case in parse_vars() where we get the base size in cfnvals and pass it to parse_var() instead, although I still don't think I can see the element size being stored for future reference. So I *think* this means there's currently no way to get the implicit multiplication by the element size, but I am not certain.
Incidentally I think you have accidentally used a "." instead of a ":" in the line:
(You've used a colon elsewhere, so this looks like just a slip. I only mention it as I happened to notice it and it may save hair pulling on your side later.)
Assuming I'm right and there's no way to have the compiler handle the indexing for you, there are three rough approaches you can take:
- Instead of writing "sessions[index]", write "sessions[index * t_session]" - STEST.pla in attached zip shows this
- Have a new word variable "session" which you initialise to "@sessions" (for 0-based loops) or "@sessions + t_session" (for 1-based loops) and add t_session to it each time round the loop, then use session as a base pointer to access the current element - the first two loops in STEST2.pla show this
- Have a new word variable "session" and do "session = @sessions + index * t_session" at the start of each loop body, then use session as a base pointer to access the current element - the last loop in STEST2.pla shows this
I've given the attached variants a quick test but it's not impossible I've done something wrong, so please take this with a pinch of salt. If you try something and it doesn't work let me know and I'll take a look!
shifters74 wrote: ↑Wed Jul 06, 2022 2:04 pm
Sorry another day of being a noob
No problem. And far from being a noob, you're probably in the top 100 PLASMA programmers on the planet!