Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 23:28 17 Feb 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Changed behaviour with STRUCTURES

Author Message
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 1094
Posted: 04:38am 17 Feb 2026
Copy link to clipboard 
Print this post

This was discovered when implementing Structures on the CMM2. I confirmed the same behaviour on the latest Picomite 6.02.01b2.
It only came to light when a previous unit test did not work as expected.
It occurs when an array element e.g. b(3) from say the array b() is passed to a SUB that is expecting an array. (Not sure why you would want to do this). This has always been accepted and inside the SUB the original array is accessed  By Reference, but inside the SUB there was an offset to the array index.(see note below).

If STRUCTUREs are implemented this offset seems to be gone and passing b(3) or b() to the SUB is equivalent with no side affects.
This post is just to note the change.



'  --------- Prior to STRUCTURES ------------------------
'  When an array element e.g b(3) is passed to a SUB expecting an array
'  it is accepted as an array, and treated as BYREF with no error/complaint.
'  BUT the array inside the SUB is offset by the array element number provided.
'  So pass b(3) and it ends up as b(0) inside the array in the SUB.
'  Inside the SUB you cannot get to b(0),b(1) or b(2)
'  If you maniplulate the array inside the SUB to write past its 256 byte
'  boundary you can inadvertantly change the adjacent previous variable,
'  if it happens to be the first variable then you write into a sensitive area
'  and can kill MMBasic !!!
'  This is not trapped as it is legal to work on the passed element as BYREF,
'  you just need to behave and know its b(0) inside the SUB !
'
' ---   UPDATE when STRUCTURES are implemented. ------
' This behaviour changes when STRUCTURES are implemented.
'   byrefArrayShifted a,b(3),c
'   byrefArrayShifted a,b(),c
' The two calls to SUB byrefArrayShiftedabove above.
' are both accepted and treated as passing the array b()
' and within the called SUB there is no offset to the array index. i.e. b(0)
' inside the SUB is b(0) of the calling code.
Edited 2026-02-17 14:39 by disco4now
F4 H7FotSF4xGT
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4241
Posted: 08:23am 17 Feb 2026
Copy link to clipboard 
Print this post

Sounds like a bug.

John
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10963
Posted: 08:27am 17 Feb 2026
Copy link to clipboard 
Print this post

If a subroutine is expecting an array and you pass it an array element then it is wrong and whatever behaviour you get shouldn't be relied on.
 
bfwolf
Senior Member

Joined: 03/01/2025
Location: Germany
Posts: 163
Posted: 10:24am 17 Feb 2026
Copy link to clipboard 
Print this post

  JohnS said  Sounds like a bug.

John


Yes, but if so, then the behavior from earlier.


  matherp said  If a subroutine is expecting an array and you pass it an array element then it is wrong and whatever behaviour you get shouldn't be relied on.


I completely agree with you!

An array element is not the same as an array of elements! Even if both are passed by reference. The reference to the array contains not only the memory address of the array elements but also information about the array dimensions.

Currently, you've probably solved this by simply (silently) ignoring the array index when the called SUB (or function) expects an array, and instead passing the entire original array. At least this way nothing bad can happen.

If you wanted a "clean" solution, you'd have to teach MMBasic TypeCasts that perform type conversion "on the fly."

Visual Basic has the CType operator (or the corresponding function) for this.

https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/ctype-operator

But I realize that this would be quite complex and also involve runtime and potentially memory usage, because temporary objects might have to be created on the stack and data copied, unless the variable management structure inherently contains a pointer to the actual memory location, which could then be set to the original data in the temporary variable instance.

I would completely understand if you said, "I'm not going to bother with that right now."

Regards, bfwolf
 
ville56
Guru

Joined: 08/06/2022
Location: Austria
Posts: 393
Posted: 11:08am 17 Feb 2026
Copy link to clipboard 
Print this post

from my understanding this not really a case for typecasting. Typecasting, for me in the context of MMBasic would be converting from integer to float and vice versa if necessary.
It is simply calling the SUB with wrong parameters(a single variable instead of an array), independently from the variable type. MMBasic could/should throw an error in this case.
                                                                 
73 de OE1HGA, Gerald
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 8560
Posted: 11:13am 17 Feb 2026
Copy link to clipboard 
Print this post

Well, it *could* but isn't it a bit of an edge case really? You can't trap every error event and sometimes it probably isn't worth it. :)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10963
Posted: 11:21am 17 Feb 2026
Copy link to clipboard 
Print this post

  Quote  from my understanding this not really a case for typecasting.


Sort of is.

In C "x[0]" would give an error buy you could cast it to a pointer "&x[0]" which is the same as passing the array "x"

UPDATE
I've looked at this more and can easily make the code revert to the original behaviour OR through an error. The error route is the better solution but could break existing programs. thoughts?
Edited 2026-02-17 21:39 by matherp
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4241
Posted: 11:24am 17 Feb 2026
Copy link to clipboard 
Print this post

I figured it was wanting/expecting an array slice.

If it's not meant to be, no worries - a note in the manual or even better throw an error.

I suppose in C, &x[3] and it would work fine
(and there's an arguably uglier-looking expression, but let's not do too much C here)

John
Edited 2026-02-17 21:26 by JohnS
 
bfwolf
Senior Member

Joined: 03/01/2025
Location: Germany
Posts: 163
Posted: 11:38am 17 Feb 2026
Copy link to clipboard 
Print this post

  ville56 said  from my understanding this not really a case for typecasting. Typecasting, for me in the context of MMBasic would be converting from integer to float and vice versa if necessary.
It is simply calling the SUB with wrong parameters(a single variable instead of an array), independently from the variable type. MMBasic could/should throw an error in this case.


Of course, one could prevent any potential abuse and make the language "foolproof," but that would require endless checks at every turn and would significantly worsen performance.

Typecasting, or type conversion, would, for example, convert an array into a subset of the array, or a single array element into an array of size 1 — if you wanted to enable that. But the effort required is considerable.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10963
Posted: 11:40am 17 Feb 2026
Copy link to clipboard 
Print this post

UPDATE
I've looked at this more and can easily make the code revert to the original behaviour OR throw an error. The error route is the better solution but could break existing programs. thoughts?
 
bfwolf
Senior Member

Joined: 03/01/2025
Location: Germany
Posts: 163
Posted: 12:00pm 17 Feb 2026
Copy link to clipboard 
Print this post

So, I think it would be possible to reverse this, but then it would have to be explicitly explained in the manual that when a single array element is passed to a subroutine/function that expects an array as an argument, it is implicitly converted to a reference to the array element, or more precisely, to an array starting at that index.

The problem is: How does `BOUND(array()[,dimension])` behave within the subroutine or function?

If it can return nonsensical values, this would have to be noted in the manual. The currently correct array boundaries could also be passed as an additional argument.

Overall, this is of course dangerous without proper type conversion.
Edited 2026-02-17 22:02 by bfwolf
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 1094
Posted: 12:11pm 17 Feb 2026
Copy link to clipboard 
Print this post

Peter,
I think at one point we had it throwing an error when fine tuning the BYVAL/BYREF implementation but took it out so it matched the previous behaviour when not using the BYREF qualifier. Reverting to the original behaviour would make it consistent across all platforms. In all the years of MMBasic the only time I have seen it mentioned was when it came up when writing the unit tests for the BYREF/BYVAL implementation.

Gerry
Edited 2026-02-17 22:15 by disco4now
F4 H7FotSF4xGT
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026