Page 1 of 1

5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 9:06 am
by Kurzer
Hello everyone,

If an array is declared as global within a procedure and the array is accessed outside the procedure before the procedure is called, the compiler will not complain about this. The program is compiled "without" errors, but then crashes with a memory access error.

Code: Select all

EnableExplicit

Procedure Test()
   Global Dim MyArray.s(1)
   MyArray(0) = "Hello"
EndProcedure

; Test()

Debug MyArray(0)

Test()
For testing simply comment in/out the commented-out line 8.
The compiler should notice this

Kind Regards,
Kurzer

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 9:13 am
by RSBasic
I can confirm that.

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 9:04 pm
by mk-soft
I don't think it's a bug.

Memory is only requested when DIM is called.
This is only done when calling in the procedure

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 9:09 pm
by Kurzer
This is correct, but I would assign this kind of "problem" to the "EnableExplicit" area. So that the use of EnableExplicit warns me of such a constellation.
It's very similar to the constellation when I try to use an undeclared variable. This is what EnableExplicit warns me about.

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 9:29 pm
by #NULL
hehe :) I always thought you can't define a zero-size array. apparently it's possible (without ExtractJSON/XMLArray). 8)

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 9:41 pm
by Kurzer
@Fred: We discussed this in the German forum and classified this type of coding as bad style.

In my opinion the compiler should prevent this kind of use of arrays. If a global array() is defined, this should only be allowed in the main scope.

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 9:41 pm
by mk-soft
Empty Array...

Code: Select all

EnableExplicit

Procedure InitArray(Size)
   Global Dim MyArray.s(Size)
EndProcedure

Debug ArraySize(MyArray())

InitArray(100)

Debug ArraySize(MyArray())

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 10:08 pm
by BarryG

Code: Select all

Procedure Test()
   Global Dim MyArray.s(1)
   MyArray(0) = "Hello"
EndProcedure

; Test()

Debug MyArray(0)
Since Test() is never called, this means the array was never created; so instead of crashing with an illegal memory error, the compiler should give the usual warning of "MyArray() is not a function, array, list..." IMO.

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Thu May 16, 2019 10:15 pm
by #NULL
BarryG wrote:Since Test() is never called, this means the array was never created; so instead of crashing with an illegal memory error, the compiler should give the usual warning of "MyArray() is not a function, array, list..." IMO.
No, MyArray *is* an array, only with zero size. And the compiler cannot easily know if the function will ever be called.

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Fri May 17, 2019 1:44 pm
by Sicro
As @mk-soft has already pointed out, you must first check if the array has been declared before accessing the array, if the case exists that the procedure is not called:

Code: Select all

Procedure test()
  Global Dim value(2)
  value(0) = 1
  value(1) = 2
  value(2) = 3
EndProcedure

test()

If ArraySize(value()) > -1
  Debug value(0)
  Debug value(1)
  Debug value(2)
Else
  Debug "Array not declared"
EndIf
PB help => ArraySize() wrote:If the array isn't yet declared (or its allocation has failed), it will return -1.
The problem also exists with normal variables:

Code: Select all

EnableExplicit

Procedure test()
  Global value = 10
EndProcedure

;test()

Debug value
It is best to avoid the keyword Global in procedures, because it messes up the compilation process.

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Fri May 17, 2019 3:04 pm
by skywalk
Sicro wrote:It is best to avoid the keyword Global in procedures, because it messes up the compilation process.
No, I use init() procedures that perform this and other memory tasks. The only element I cannot house within an init() procedure are Prototypes.

Code: Select all

EnableExplicit
Macro do1()
  Prototype.i x(a.i,b.i)
EndMacro
Procedure Init()
  #MY_CONST1     = 1
  Global.i gMY10 = 10
  Global Dim MyArray.s(1)
  MyArray(0) = "Hello"
  MyArray(1) = "World"
EndProcedure
Procedure Do2()
  ProcedureReturn gMY10
EndProcedure
Init()
Debug MyArray(0) + MyArray(1)
Debug Do2()
Debug #MY_CONST1

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Fri May 17, 2019 10:38 pm
by Sicro
skywalk wrote:No, I use init() procedures that perform this and other memory tasks.
What is wrong with using a macro or a comment and main code instead of a procedure as Init()?

Code: Select all

Macro Init()
  Global NewMap settings$()
  ; More init codes
EndMacro
Init()
or

Code: Select all

;- Initialising
Global NewMap settings$()
; More init codes

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Sat May 18, 2019 3:24 am
by skywalk
Think dll. :idea:

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Sat May 18, 2019 11:03 am
by mk-soft
Link DLL´s:
viewtopic.php?p=485833#p485833
Fred wrote:AttachProcess() should be called on linux as well, if not it's a bug. You can also declare list in procedure if needed, just not in the main code.
This is my way for Modules and DLL´s

Code: Select all

DeclareModule MyModule
  Declare DoAny(Index)
EndDeclareModule

Module MyModule
  
  Procedure InitModule()
    Global Dim MyArray(1)
    Global NewList MyList()
    MyArray(0) = 100
  EndProcedure : InitModule()
  
  Procedure DoAny(Index)
    ProcedureReturn MyArray(Index)
  EndProcedure
  
EndModule

Debug MyModule::DoAny(0)

Re: 5.70 LTS x64: IMA using a global array in a procedure

Posted: Sat May 18, 2019 11:07 am
by Sicro
skywalk wrote:Think dll. :idea:
Then use

Code: Select all

Procedure AttachProcess(Instance)
  ; Your init codes
EndProcedure
Then you don't have to worry whether the init codes are executed or not, because the AttachProcess() procedure is executed automatically.