![]() |
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 StatesPosts: 59 |
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: AustraliaPosts: 6283 |
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. 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 StatesPosts: 59 |
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 StatesPosts: 59 |
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 KingdomPosts: 4044 |
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 KingdomPosts: 10310 |
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 RepublicPosts: 533 |
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 KingdomPosts: 10310 |
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 KingdomPosts: 4311 |
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 StatesPosts: 59 |
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 StatesPosts: 59 |
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 RepublicPosts: 533 |
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 StatesPosts: 3378 |
I also am tending to use this. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |