Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 10:32 01 Aug 2025 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 : CMM2: Bug in MATH V_CROSS with OPTION BASE 0

Author Message
Nelno

Regular Member

Joined: 22/01/2021
Location: United States
Posts: 59
Posted: 03:29am 08 Feb 2021
Copy link to clipboard 
Print this post

The following code causes the error "Error in line 5: Argument 1 must be a 3 element floating point array"


option base 0
dim float v1(3)
dim float v2(3)
dim float out(3)
math v_cross v1(),v2(),out()
end


Changing OPTION BASE 1 allows the code to run without error.
Changing the dims of each array to 2 (with OPTION BASE 0) also allows it to run, though it's probably overwriting memory past the ends of the arrays in that case.

From looking at the MMBASIC code I think this may be erroring on the numcols!=2 test, since with OptionBase == 0, the calculation to compute numcols will yield 3, where as it would yield 2 with OptionBase == 1. This also explains why changing the dimension to 2 works when OptionBase == 0.
Edited 2021-02-08 13:31 by Nelno
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 04:05am 08 Feb 2021
Copy link to clipboard 
Print this post

With OPTION BASE 0, dim float v1(3) will produce 4 elements : 0,1,2,3

Think of DIM as declaring the highest element number, not the number of element.

The manual could do with a change to make that clearer.
  Quote  Following the variable's name the dimensions are specified by a list of
numbers separated by commas and enclosed in brackets. For example:
DIM array(10, 20)
Each number specifies the number of elements in each dimension. Normally
the numbering of each dimension starts at 0 but the OPTION BASE
command can be used to change this to 1.
The above example specifies a two dimensional array with 11 elements (0 to
10) in the first dimension and 21 (0 to 20) in the second dimension.


I would change the sentence
"Each number specifies the number of elements in each dimension." to
"Each number specifies the maximum element number in each dimension."

Jim
VK7JH
MMedit
 
Nelno

Regular Member

Joined: 22/01/2021
Location: United States
Posts: 59
Posted: 04:38am 08 Feb 2021
Copy link to clipboard 
Print this post

Thanks! That would be where my confusion lies!

It's an interesting question as to what DIM is really supposed to do in BASIC. I checked two old 80's BASIC manuals I have (TI-99/4A Extended Basic and SVI-328 BASIC Reference Manual) and one simply says it is to reserve memory (which implies that number passed to it is the total bytes in the array, not the max index), while the other says it is "To specify the maximum values for array subscripts and to allocate memory accordingly." The second one seems to make it clear that it's the maximum subscript value being specified, like MMBASIC seems to do.

So, I guess this is actually working as intended and I do not need to worry about the interpreter overwriting memory anywhere. I do need to go back and adjust all of my array declarations, though, to have - 1 everywhere.
 
Nelno

Regular Member

Joined: 22/01/2021
Location: United States
Posts: 59
Posted: 04:52am 08 Feb 2021
Copy link to clipboard 
Print this post

There's a little more to it that this.

To declare a local array with 4 elements I used:


option base 0
local float fvx(4)


But is that really the same as:


option base 0
dim float fvx(4)


I'm guessing so, but I now feel I need to verify that in the MMBASIC implementation code. EDIT: to put that to rest, "LOCAL" and "DIM" use the same code in MMBASIC so they end up doing the exact same thing.

This is also going to be fairly confusing for me to use:


dim float fvx(3)


Because my brain will almost certainly interpret that as a 3-element array, not a 4-element array. It is also impossible to know from just that line of code, because you must now know what the OPTION BASE value is to know how large of an array it is.

In this particular case, it's the x-value of vertices on a cube face, of which there must be 4, but dim float fvx(3) will make for some confusion if someone were trying to understand that code without the OPTION BASE context.

This has me thinking I should just use OPTION BASE 1 and that the best way to implement DIM (in light of having OPTION BASE at all) would be to make it specify the number of elements in the array, not the maximum index value. My guess is that's not a reasonable thing to do now, though, without causing pre-existing OPTION BASE 0 code (that was using DIM correctly to specify the maximum index value) to suddenly end up with a lot of arrays that are 1 element too small.
Edited 2021-02-08 14:56 by Nelno
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 08:29am 08 Feb 2021
Copy link to clipboard 
Print this post

You may well want just to use OPTION BASE 1

LOCAL & DIM are different in that LOCAL declares something visible only in the surrounding SUB/FUNCTION.

If used in the main part I don't know whether LOCAL is different but I would (naively perhaps) expect it either would be an error (not my preferred choice) or would declare something only visible within the main part (i.e. not visible within SUBs or FUNCTIONs).

By "visible" I mean able to be accessed by code explicitly specifying it by name (roughly what many languages talk about as lexical scoping).

I realise I've never tried LOCAL in the main part...

John
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 08:31am 08 Feb 2021
Copy link to clipboard 
Print this post

Just to be clear to anyone reading this thread - there is no bug just a misunderstanding of the DIM command on the part of the OP
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 533
Posted: 12:27pm 08 Feb 2021
Copy link to clipboard 
Print this post

It will be nice if it will be possible also

OPTION BASE 0
DIM STRING s(0)

...
Jiri
Napoleon Commander and SimplEd for CMM2 (GitHub),  CMM2.fun
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 12:50pm 08 Feb 2021
Copy link to clipboard 
Print this post

  Quote  It will be nice if it will be possible also


I agree but it is not possible without massive re-write of core MMBasic
Edited 2021-02-08 22:50 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 01:05pm 08 Feb 2021
Copy link to clipboard 
Print this post

I find this utility function can help if you can't wrap your brain around the 'x' in Dim a(x) being the upper bound and not the array capacity:

' Gets the upper-bound that should be used to dimension an array of the given
' capacity, irrespective of OPTION BASE.
'
' e.g. To create a string array that can hold 10 elements:
'        Dim my_array$(array.new%(10))
Function array.new%(capacity%)
 array.new% = capacity% + Mm.Info(Option Base) - 1
End Function


Best wishes,

Tom
Edited 2021-02-08 23:05 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Nelno

Regular Member

Joined: 22/01/2021
Location: United States
Posts: 59
Posted: 10:07pm 08 Feb 2021
Copy link to clipboard 
Print this post

  JohnS said  You may well want just to use OPTION BASE 1

LOCAL & DIM are different in that LOCAL declares something visible only in the surrounding SUB/FUNCTION.

If used in the main part I don't know whether LOCAL is different but I would (naively perhaps) expect it either would be an error (not my preferred choice) or would declare something only visible within the main part (i.e. not visible within SUBs or FUNCTIONs).

By "visible" I mean able to be accessed by code explicitly specifying it by name (roughly what many languages talk about as lexical scoping).

I realise I've never tried LOCAL in the main part...

John


I use LOCAL extensively to declare variables local to a function and it works as I expect in that capacity (though don't put one in a loop -- it will try to re-declare the variable each time through, resulting in an error). But my worry was that maybe it didn't treat the array "size" declaration in the same way as DIM. It appears it does, as the MMBASIC code says that LOCAL and DIM both use the same cmd_dim function with the only difference being the declared scope of the array.

LOCAL in the main part will give "not allowed here" error or something similar to that, I believe.

As for using OPTION BASE 1... yes, I'm leaning towards that. I think it's probably just confusing later down the line to use OPTION BASE 0 and have all of my arrays declared as  DIM A(ACTUAL_SIZE_OF_ARRAY - 1)

-Jonathan
 
Nelno

Regular Member

Joined: 22/01/2021
Location: United States
Posts: 59
Posted: 10:13pm 08 Feb 2021
Copy link to clipboard 
Print this post

  jirsoft said  It will be nice if it will be possible also

OPTION BASE 0
DIM STRING s(0)

...


Theoretically that should work, except that it appears that MMBASIC doesn't allow declaration of an array with only 1 element. That makes sense from a pre-declared array standpoint, but not necessarily with dynamically allocated buffers.


Both of these cause "Error in line 2: Dimensions":



option base 0
dim float a(0)


or


option base 1
dim float a(1)
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 533
Posted: 10:35pm 08 Feb 2021
Copy link to clipboard 
Print this post

  Nelno said  
  jirsoft said  It will be nice if it will be possible also

OPTION BASE 0
DIM STRING s(0)

...


Theoretically that should work, except that it appears that MMBASIC doesn't allow declaration of an array with only 1 element. That makes sense from a pre-declared array standpoint, but not necessarily with dynamically allocated buffers.


Both of these cause "Error in line 2: Dimensions":



option base 0
dim float a(0)


or


option base 1
dim float a(1)


Yeah, I know we have this issue. I have problem with it when I'm giving to my TUI.INC arrays with lists as parameter.

Simplest "solution" I found is to give arrays with BASE 0 but use it like BASE 1 (simply ignore element 0)...
Jiri
Napoleon Commander and SimplEd for CMM2 (GitHub),  CMM2.fun
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 10:37pm 08 Feb 2021
Copy link to clipboard 
Print this post

  jirsoft said  Simplest "solution" I found is to give arrays with BASE 0 but use it like BASE 1 (simply ignore element 0)...

I also am tending to use this.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
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 2025