Is safe to save pointers in an integer array?

General FreeBASIC programming questions.
Post Reply
Julcar
Posts: 141
Joined: Oct 19, 2010 18:52
Contact:

Is safe to save pointers in an integer array?

Post by Julcar »

I've been using this method for a while:

I have an array for registering external procedure loaders:

Code: Select all

DIM SHARED ArrayLoaders() AS UINTEGER

SUB RegisterLoader(LoaderPointer AS UINTEGER)
  DIM LoaderIndex AS LONG = UBOUND(ArrayLoaders) + 1
  REDIM PRESERVE ArrayLoaders(LoaderIndex)
  ArrayLoaders(LoaderIndex) = LoaderPointer
END SUB

SUB RunLoaders()
  DIM LoaderEntry AS SUB()
  DIM LoaderIndex AS LONG = UBOUND(ArrayLoaders)
  IF LoaderIndex >= 0 THEN
    FOR i AS LONG = 0 TO LoaderIndex
      LoaderEntry = ArrayLoaders(i)
      IF LoaderEntry > 0 THEN
        LoaderEntry()
      END IF
    NEXT
  END IF
END SUB
So, in modules I can call this:

Code: Select all

'These are the names of existing procedures
RegisterLoader(CINT(ProcPtr(LoadSession)))
RegisterLoader(CINT(ProcPtr(LoadUserData)))
And in my main module I can just call RunLoaders() and it's easy to call a lot of functions from one line, and everything works OK, but when compiling I get the following warning:

core\modules.bas(96) warning 4(1): Suspicious pointer assignment

which line 96 is:

LoaderEntry = ArrayLoaders(i)

I tried converting the UINTEGER value to PTR with LoaderEntry = CPTR(UINTEGER PTR, ArrayLoaders(i)) but the warning persists.
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Is safe to save pointers in an integer array?

Post by fxm »

Code: Select all

DIM SHARED ArrayLoaders() AS ANY PTR

SUB RegisterLoader(LoaderPointer AS ANY PTR)
  DIM LoaderIndex AS LONG = UBOUND(ArrayLoaders) + 1
  REDIM PRESERVE ArrayLoaders(LoaderIndex)
  ArrayLoaders(LoaderIndex) = LoaderPointer
END SUB

SUB RunLoaders()
  DIM LoaderEntry AS SUB()
  DIM LoaderIndex AS LONG = UBOUND(ArrayLoaders)
  IF LoaderIndex >= 0 THEN
    FOR i AS LONG = 0 TO LoaderIndex
      LoaderEntry = ArrayLoaders(i)
      IF LoaderEntry > 0 THEN
        LoaderEntry()
      END IF
    NEXT
  END IF
END SUB

Code: Select all

'These are the names of existing procedures
RegisterLoader(ProcPtr(LoadSession))
RegisterLoader(ProcPtr(LoadUserData))
Julcar
Posts: 141
Joined: Oct 19, 2010 18:52
Contact:

Re: Is safe to save pointers in an integer array?

Post by Julcar »

Thanks for the code, but...

There's some alternative to the keyword "ANY"??

To be honest, I don't like to see the "ANY PTR" in my code (just a matter of taste)
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Is safe to save pointers in an integer array?

Post by fxm »

In your particular application, because calling only procedures of the same type (sub without parameters), you can use 'SUB()' as type (as you declared 'LoaderEntry').

Code: Select all

DIM SHARED ArrayLoaders() AS SUB()

SUB RegisterLoader(LoaderPointer AS SUB())
  DIM LoaderIndex AS LONG = UBOUND(ArrayLoaders) + 1
  REDIM PRESERVE ArrayLoaders(LoaderIndex)
  ArrayLoaders(LoaderIndex) = LoaderPointer
END SUB

SUB RunLoaders()
  DIM LoaderEntry AS SUB()
  DIM LoaderIndex AS LONG = UBOUND(ArrayLoaders)
  IF LoaderIndex >= 0 THEN
    FOR i AS LONG = 0 TO LoaderIndex
      LoaderEntry = ArrayLoaders(i)
      IF LoaderEntry > 0 THEN
        LoaderEntry()
      END IF
    NEXT
  END IF
END SUB

Code: Select all

'These are the names of existing procedures
RegisterLoader(ProcPtr(LoadSession))
RegisterLoader(ProcPtr(LoadUserData))
Julcar
Posts: 141
Joined: Oct 19, 2010 18:52
Contact:

Re: Is safe to save pointers in an integer array?

Post by Julcar »

That solution was more appealing, but still some ugly for me, however it gave me a great idea, I started using the TypeOf() macro and found the correct pointer type I have to pass as 1st argument to CPTR(), thankyou so much. This commit is dedicated to you :)
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Is safe to save pointers in an integer array?

Post by fxm »

I don't understand this reluctance to use the 'Any Ptr' type.

You have to store procedure pointers but of different types ('Sub()', 'Function() As String', 'Function(As String) As String') in an array.
For me the most suitable type for this array is 'Any Ptr' rather than 'Integer'.
Moreover, using 'Any Ptr' avoids having to code an explicit conversion when assigning each type of pointer.
Julcar
Posts: 141
Joined: Oct 19, 2010 18:52
Contact:

Re: Is safe to save pointers in an integer array?

Post by Julcar »

fxm wrote:I don't understand this reluctance to use the 'Any Ptr' type.

You have to store procedure pointers but of different types ('Sub()', 'Function() As String', 'Function(As String) As String') in an array.
For me the most suitable type for this array is 'Any Ptr' rather than 'Integer'.
Moreover, using 'Any Ptr' avoids having to code an explicit conversion when assigning each type of pointer.
As said before, it's just a matter of taste, it reminds me in some way the variant data type in VBScript, I preffer to know what specific data type (or pointer type) that a variable has.
fxm
Moderator
Posts: 12577
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Is safe to save pointers in an integer array?

Post by fxm »

So your commit which is dedicated to me is to be taken by me in the second degree as a joke.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Is safe to save pointers in an integer array?

Post by counting_pine »

I agree with fxm that Any Ptr is the most appropriate kind of datatype for storing varying kinds of pointers.

My suggestion would be to make a Typedef once for Any Ptr (perhaps also for Sub/Function As ... or anything else you need), then you can use the Typedefs everywhere you need to in code.
You could also create macros to do the conversions between pointer types.
Post Reply