Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-10

Problem passing pointers to "hidden" procedure

3 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Unknown author

As part of an attempt at multi-threading, I have had to move many things that used to be global into the Implementation parts of units in order to enforce privacy. When I moved a routine passed as a parameter and put it inside the routine to be threaded, the program ceased to work. I append the essential code abstracted from my program:

Program Test ;
Uses TestSub ;
Begin
  Test_it ;
End.
Unit TestSub ;
Interface
Procedure Test_it ;
Implementation
Const
  Chunksize = 24 ;
  Arraysize = 100 ;
Type
  ProcT = Procedure(Const P1, P2 : Pointer) ;
  BArray  = Array[0..1999999999] Of Byte ;
  Chunk   = Array[0..Chunksize-1] Of Byte ;
Var
  Data : Array[0..Arraysize-1] Of Chunk ;
Procedure Do_it(Var A ; Const N, NB : Longint ; F : ProcT) ;
Begin
  Writeln('Do_it: expect'#9, Longint(@A), #9, Longint(@Barray(A)[NB])) ;
  F(@BArray(A)[0], @BArray(A)[NB]) ;
End ; { Do_it }
Procedure PrPublic(Const f1, f2 : Pointer) ; { Visible }
Begin
  Writeln('PrPublic'#9, Longint(f1), #9, Longint(f2)) ;
End ; { PrPublic }
Procedure Test_it ;
  Procedure PrPrivate(Const f1, f2 : Pointer) ; { Private }
  Begin
    Writeln('PrPrivate'#9, Longint(f1), #9, Longint(f2)) ;
  End ; { PrPrivate }
Begin { Test_it }
  Do_it(Data, Arraysize, Chunksize, @PrPublic) ;
  Do_it(Data, Arraysize, Chunksize, @PrPrivate) ;
End ; { Test_it }
End.

Output:
Running "c:\fpc\2.4.2\exe\test.exe "
Do_it: expect 4252848 4252872
PrPublic 4252848 4252872
Do_it: expect 4252848`4252872
PrPrivate 4252872 4234688

When the routine being passed as a parameter is in the top level of the unit, "PrPublic", all is well; the expected pointers are passed. When an identical routine "PrPrivate" is hidden inside the top level routine "Test_it", the expected 2nd pointer appears in place of the first and an apparently random pointer appears second.

What am I doing wrong?

Andrew Bennett

Ludo Brands
to Unknown author
Show quoted text 9 lines
When the routine being passed as a parameter is in the top level of the unit, "PrPublic", all is well; the expected pointers are passed. When an identical routine "PrPrivate" is hidden inside the top level routine "Test_it", the expected 2nd pointer appears in place of the first and an apparently random pointer appears second. What am I doing wrong?

You can't assign private functions to procedural types. http://www.freepascal.org/docs-html/ref/refse17.html says "A global procedure or function address". The delphi 6 help is even more explicit: "Nested procedures and functions (routines declared within other routines) cannot be used as procedural values."

Ludo

Sven Barth
to Unknown author: As part of an attempt at multi-threading, I have had to move many things that used to be…
Show quoted text 7 lines
As part of an attempt at multi-threading, I have had to move many things that used to be global into the Implementation parts of units in order to enforce privacy. When I moved a routine passed as a parameter and put it inside the routine to be threaded, the program ceased to work. I append the essential code abstracted from my program:

[snip]

What am I doing wrong?

As Ludo wrote local procedures/functions are not supposed to be passed around as function pointers. In trunk and the upcoming 2.6 there is a possibilty though: nested procedure variables.

For a description you can take a look at this commit message: http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=15694

Especially take a look at the tests in tests/test/tmaclocalprocparam* mentioned in the commit log for examples of this feature.

Regards,
Sven