Procedural parameters and types: bug report and work-around

Fri, 19 Sep 1997 16:36:15 +0100 (MET)


Dear GPC developers:

  In my recent post to the list about compiler warnings with "incompatible
pointers" (when using user-defined types), I mentioned that I had a similar
problem with procedural types/parameters.  This statement is much, much too
vague for a bug report, so here is an example that demonstrates the problem.

(Peter, thanks for the speedy response to my first bug report!)

Note that, contrary to the "incompatible pointers" problem that I reported a
few days ago, the program below does *not* compile (unless the work-around in
the example is used).

In the example below, there is one unit (u4) and the main program.  The
example demonstrates all facets of the bug (type inconsistencies) that I have
discovered, and includes a simple bug work-around (I am assuming here that
the typecast needed to fix the problem is not a feature ...).

------------------------- u4. pas ----------------------------------

unit u4;   { Note the start-up code }

interface

type
  procType = ^procedure (var x : Integer);

procedure proc3 (procedure f (var x : Integer));
procedure proc4 (f : procType);


implementation

{ Example with Procedural parameter (Standard Pascal) }
procedure proc3 (procedure f (var x : Integer));
var
  y : Integer;

begin
  f(y);
  Writeln (y);
end; { proc3 }

{ Example with Procedural Types (Borland-like) }
procedure proc4 (f : procType);
var
  y : Integer;

begin
  f(y);
  Writeln (y);
end; { proc4 }


procedure Test (var b : Integer);
begin
  b := 2003;
end;


begin
  { Both of these call compile and work.  Note that the procedure   }
  { "Test" which is passed as argument is in the same unit.  Hence, }
  { there is no need for a typecast (as in the main program).       }

  proc3 (Test);  { Procedural parameter example }
  proc4 (Test);  { Procedural type example }
end.



--------------------------------- mainprg1.pas ----------------------

program Mainprg1;

uses
  u4;

procedure pp (var k : Integer);
begin
  k := 120469;
end; { pp }

begin
  { Below the procedure passed as argument (pp) resides in another    }
  { module than proc3/proc4.  The code will only compile when there   }
  { is a type cast.  This applies both to procedural parameters       }
  { (Standard Pascal) and types (Borland-like).                       }

  { These lines do not compile }
  proc3 (pp);   { Line 18 }
  proc4 (pp);   { Line 19 }

  { With the typecast everything works OK!  Even in the standard   }
  { Pascal version (proc3) which does not use the type "ProcType". }

  proc4 (ProcType (pp));    { Bug work-around for Borland-like example   }
  proc3 (ProcType (pp));    { It also works for Standard Pascal example  }
end.


------------------------------------------------------------------------

I compile with

  gpc -o mainprg1.exe mainprg.pas --automake

Compiler output:

  mainprg1.pas: In function `program_Mainprg1':
  mainprg1.pas:18: too few arguments to function `Pp'
  mainprg1.pas:18: invalid use of void expression
  mainprg1.pas:19: too few arguments to function `Pp'
  mainprg1.pas:19: invalid use of void expression

(same error for procedural types and parameters).


When line 18 and 19 is deleted, the program compiles correctly (because of
the typecast bug work-around), and outputs (as intended)

  2003             
  2003
  120469
  120469

The first two lines are from the start up code (procedural argument Test in
unit u4), the third and fourth from "pp" in the main program.

Finally (for the record), I use GPC version 970714 (beta), DJGPP precompiled
binary.

Sincerely,

Jesper Lund



Jesper Lund (jel@hha.dk)

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