Procedural Types

Mon, 7 Jul 1997 12:23:25 +0200 (MET DST)


Hallo, Bernhard, hello, everybody!

According to Bernhard Tschirren:
> 
> [...] The following program
> demonstrates this bug. In some (RANDOM!) cases, the program works, in others
> it prints out only the first letter of the 'OK'. [...]


(*$if 0 *)


Now we are in trouble: I cannot reproduce this bug, neither on DJGPP, nor
on Linux.

I'd like to ask you to do further analysis on this:

  - Is the address returned by `Name1' and `Name2' the same?  (It should be!)

  - What are the bytes pointed to by both returned `CString's?

I mean something like the following:


    Program Bug02;

    Uses
        Bug02_U in 'b5u.pas';

    {$X+}

    Type
        ByteArray = array [ 0..3 ] of Byte;
        ByteArrayPtr = ^ByteArray;

    Var
        ProcRec : TProcRec;
        P1, P2: CString;
        i: Integer;

    Function TheName : CString;
        Begin
            TheName := 'OK';
        End;

    Begin
        ProcRec.Name1 := @TheName;
        ProcRec.Name2 := @TheName;
        P1:= ProcRec.Name1^;
        P2:= ProcRec.Name2^;
        writeln ( Integer ( P1 ) );
        writeln ( Integer ( P2 ) );
        writeln ( P1 );
        writeln ( P2 );
        for i:= 0 to 3 do
          write ( ByteArrayPtr ( P1 )^ [ i ] : 4 );
        writeln;
        for i:= 0 to 3 do
          write ( ByteArrayPtr ( P2 )^ [ i ] : 4 );
        writeln;
    End.


On my system, the result is

    5456
    5456
    OK
    OK
      79  75   0 144
      79  75   0 144

as it should be.  (The 5456 and 144 are fixed, but arbitrary numbers.)


(*$else *)


Ah - now I have it!  :-)  With high probability that's another shape
of a known bug:  You cannot assign procedures defined in a *program*
to procedural variables (or procedural pointers, like in your example). 
:-(

To check this, please move `TheName' to a Unit (either `Bug02_u' or
another one), and retry.  

These procedures are treated as local subprocedures of the main
program which is a procedure by itself.  This is the source of
a lot of trouble, also in other contexts, but it is necessary to
make some nonlocal `goto's work which are required by Extended
Pascal.  (No, I don't use `goto', and I don't know more about
this, sorry.  If I had a test program for these nonlocal `goto's,
I could try to make the other stuff work *without* breaking `goto';
right now I don't dare to touch this. ;-)


(*$endif *)


Thanks for your help, 

    Peter

 Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
 maintainer GNU Pascal [970624] - http://home.pages.de/~gnu-pascal/ [970125]




Peter Gerwinski (peter@agnes.dida.physik.uni-essen.de)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es