|
Post by Walt Decker on Feb 20, 2021 16:40:22 GMT -5
Are arrays and STRUCTs declared in a SUB/FUNCTION global?
I could find nothing concerning the scope of those objects when declared in one of those modules.
|
|
|
Post by Brandon Parker on Feb 20, 2021 21:07:13 GMT -5
Arrays and Structs are always global. You can just plop them at the top of the program of have a Function/Subroutine that runs once to create them when you need them for the first time.
{:0)
Brandon Parker
|
|
|
Post by Walt Decker on Feb 21, 2021 9:41:19 GMT -5
If arrays and structs are always global then this should throw an error:
' DIM A(0) STRUCT tStr, B AS LONG, C AS PTR B = 0
B = FN.Preserve()
WAIT END
FUNCTION FN.Preserve() STRUCT tStr, B AS PTR, C AS LONG, D AS SHORT DIM A(10, 1) FN.Preserve = 1 END FUNCTION '
|
|
|
Post by Brandon Parker on Feb 21, 2021 11:13:10 GMT -5
Not really ...
This is why you should only declare Structs and arrays once. Understanding how the language works is paramount to proper programming of it.
The "Dim" command dimensions an array. If the array already exists it redimensions the array; you would lose any data stored in the original elements of the array.
The "Struct" command is the same. It instantiates the structure memory space. If your code creates a structure with the same name the old structure is lost; the structure would then point to the new one.
This is why you should really only dimension an array or structure once and then work from there. This is also why I wrote my Dynamic Array library and the User Type/Class stuff.
Long story short, if you have different objects then they should have different names, and you should only declare arrays/structures once to be safe.
{:0)
Brandon Parker
|
|
|
Post by Walt Decker on Feb 21, 2021 12:10:22 GMT -5
I am using LB PRO. Apparently in that arrays declared in a sub/function are local to the module whereas structs are indeed global:
B$ = FN.ReDim$()
PRINT tStr.A.struct PRINT B$, A(0,0) '<--- Compile error: A is single dimension
WAIT END
'------------------------------------------------------------------------------- '-------------------------------------------------------------------------------
FUNCTION FN.ReDim$()
STRUCT tStr, A AS LONG, B AS SHORT
DIM A(0, 1) A(0, 0) = 1 A(0, 1) = 1
tStr.A.struct = 255
FN.ReDim$ = "Ok" END FUNCTION
|
|
|
Post by Rod on Feb 21, 2021 12:19:20 GMT -5
No, Brandon is correct. ALL arrays are global. I always declare them at the head of the program. Declaring them elsewhere runs the risk of the program / compiler attempting to use them before they have been declared.
Since your function has not been called / compiled the array has yet to be declared, as the compiler sees it.
I have come across the issue you show more than once without properly understanding what was going wrong. This prompts my habit of declaring arrays early in the code.
|
|
|
Post by Walt Decker on Feb 21, 2021 12:41:20 GMT -5
Then there is something wrong with the compiler. The function is called before the print statement.
|
|
|
Post by Brandon Parker on Feb 21, 2021 13:31:07 GMT -5
Yeah, that looks like a simple parsing issue where the compiler is expecting A(x,y) to be dimensioned and is not catching the fact that the function is called prior to executing the first statement for dealing with the array. Or, it was designed that way ...
While you can get away with instantiating Single-Dimension arrays inside Subs/Functions, the compiler simply will not allow you to do this with Double-Dimensioned arrays. I think it most likely has to do with the fact that single-dimension arrays are automatically made available up to element number 10 whereas double-dimension arrays are not. So, in essence, the compiler makes all of your single-dimension arrays available for you from the start, but not double-dimension arrays. When you "Dim"/"ReDim" a single-dimension array in a Sub/Function it just reinstantiating it. Since double-dimension arrays do not get this special treatment, you MUST declare/"Dim" them prior to any code utilizing them as read from top to bottom of your code.
In reality, this is probably something Carl could change in V5 if he wanted to.
So, in short, you really just need to dimension all of your arrays/structs at the start of your program's code. And, if you really are worried about the Zero'th elements taking up space for the Dim'd double-dimensioned arrays you can actually Dim/ReDim with -1 as the specified element count. This is not something that is documented, but it is something that I came across when writing my Dynamic Array library. This, as far as I can tell, makes LB aware of the array's given name, but does not instantiate any space for the named array.
So, you could say ...
Dim myArray(-1, -1)
... for any array that you would ever use in the program. Then, you could Dim/ReDim a double-dimensioned array within the Sub/Function with impunity.
Before declaring that something is broken though, I think we should all first see if there is a reason why it might behave in such a manner. Double-Dimensioned arrays are simply treated differently than Single-Dimensioned arrays ...
{:0)
Brandon Parker
|
|
|
Post by Rod on Feb 21, 2021 14:47:38 GMT -5
The compiler does not "call" the function it just compiles the code sequentially, so it does not see the dim statement in time.
I have to say your attention to detail is refreshing and making us all think!
|
|
|
Post by tsh73 on Feb 21, 2021 15:00:33 GMT -5
Double dimensioned, undimmed, works OK
a(3,1)=7 print a(3,0) print a(3,1) Actually. More strange thing happens.
With single dimensioned array you get a(0)..a(10) instantly - you request it's value - say print - and get 0
If you request value from 2d undimmed array, say print a(5,1) you get "array a() is 'one' dimensional" error But if you assign to 2d undimmed array, say a(5,0)=7 after that you can use a(0,0) to a(10,10).
Also DIM not have tobe executed at all to work (that's strange)
for i = 1 to 10 print i, a(i) next for i = 1 to 10 print i, b(i) 'it sure breaks at i=6 'Subscript out of range: 6, b() next
'this is never called sub test dim b(5) end sub
Attempt to 'mask' that 5 makes things worse
for i = 1 to 10 print i, a(i) next
for i = 1 to 10 print i, b(i) 'it breaks at i=1 'Subscript out of range: 1, b() next
'this is never called sub test n=5 dim b(n) end sub
|
|
|
Post by Rod on Feb 21, 2021 15:25:14 GMT -5
I think the array handling has changed a little. I always thought that you needed to dim above 11 elements So a(11) undimmed would give an error. I always thought that two dimensioned arrays always needed declared. But that seems to have changed.
"DIM sets the maximum size of an array. Any array can be dimensioned to have as many elements as memory allows. If an array is not DIMensioned explicitly, then the array will be limited to 11 elements, 0 to 10. Non DIMensioned double subscript arrays will be limited to 100 elements 0 to 9 by 0 to 9. The DIM statement can be followed by a list of arrays to be dimensioned, separated by commas."
So now you can have a(10,10) without declaration or dimming, but you must "set" it for it to exist.
As Anatoly has shown if it is not "set" ie used, then it does not exist. So back to the original problem. If you have not "declared" an array by either dimming it or setting one element then it does not exist and the compiler will trip up.
|
|
|
Post by Rod on Feb 21, 2021 15:33:37 GMT -5
On balance, I think we do have a problem with the compiler. But it can be avoided by declaring arrays up front.
|
|
|
Post by Walt Decker on Feb 21, 2021 15:37:16 GMT -5
Seems to me that all this points to a problem in compiler design. Perhaps, if the compiler is sequential, a simple solution would be to declare arrays as global in the body and local in modules, e. g.:
GLOBAL A(0, 0)
SUB W
LOCAL A(0)
END SUB
|
|
|
Post by Brandon Parker on Feb 21, 2021 21:33:05 GMT -5
Yeah, but ... maybe it was designed the way it is implemented. Only Carl would be able to confirm.
Either way, you can always accomplish what you are after if you post what you want to achieve.
{:0)
Brandon Parker
|
|
|
Post by Rod on Feb 22, 2021 3:39:13 GMT -5
Just to clear up one issue. We have gotten into the bad habit of describing arrays as "global by DEFAULT". The obvious implication that Walt has picked up on, is that the user can choose.
That's not the case. Arrays are "global by DESIGN" That's the phrase we should use. There is no such thing as a local array.
|
|