Sign in Join

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

Mailing lists / fpc-pascal / 2016-12

Question on type helpers

11 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Bart

Hi,

Why is it that type helpers must be declared in the Interface section of a unit and cannot be private in Implementation section?

Consider this (useless) example:

unit thtest;
{$mode objfpc}{$H+}
{$modeswitch typehelpers}
interface
type
  TSomeType = record end;
  TA = Array of TSomeType;
  { TAHelper }
  TAHelper = type helper for TA
    constructor Create(A: TA);
    procedure DoIt;
  end;
procedure X;
implementation
procedure X;
var
  A: TA;
begin
  A.DoIt;
end;

{ TAHelper }

constructor TAHelper.Create(A: TA);
begin
  Self := A;
end;
procedure TAHelper.DoIt;
begin
  ;
end;
end.

This compiles fine.
But when you move the declaration of TAHelper to the implementation section, then you get a compiler error:

thtest.pp(21,5) Fatal: Syntax error, "CREATE" expected but "DOIT" found
Line 21 is
  A.DoIt;

I'm using fpc 3.0.0 (32-bit) on Windows.

Bart

Reply by email

Sven Barth
to Bart
"Bart" wrote 60 lines
Hi, Why is it that type helpers must be declared in the Interface section of a unit and cannot be private in Implementation section? Consider this (useless) example: unit thtest; {$mode objfpc}{$H+} {$modeswitch typehelpers} interface type TSomeType = record end; TA = Array of TSomeType; { TAHelper } TAHelper = type helper for TA constructor Create(A: TA); procedure DoIt; end; procedure X; implementation procedure X; var A: TA; begin A.DoIt; end; { TAHelper } constructor TAHelper.Create(A: TA); begin Self := A; end; procedure TAHelper.DoIt; begin ; end; end. This compiles fine. But when you move the declaration of TAHelper to the implementation section, then you get a compiler error: thtest.pp(21,5) Fatal: Syntax error, "CREATE" expected but "DOIT" found Line 21 is A.DoIt; I'm using fpc 3.0.0 (32-bit) on Windows.

You did put the helper declaration before the implementation of X, right?

If you still have a problem, please open a bug report with an example (cause that should definitely work).

Regards,
Sven

Reply by email

Bart
to Sven Barth
Sven Barth wrote
You did put the helper declaration before the implementation of X, right?

Oops!

If you still have a problem, please open a bug report with an example (cause that should definitely work).

This is from my oiginal code.
I stripped away anything that did not influence this (lots of methods, uses clause for sysutils,class,lazutf8).

======================================
unit thtest;
{$mode objfpc}{$H+}
{$modeswitch typehelpers}
interface
type
  TStringArray = array of String;
  { TStringTable }
  TStringTable = class
  private
    FRows: array of TStringArray;
  protected
  public
    procedure DeleteCol(Index: Integer);
    function InsertCol(Index: Integer; Values: array of String): Integer;
  end;
implementation
  { TStringArrayHelper }
type
  TStringArrayHelper = type helper for TStringArray
    constructor Create(AValue: TStringArray); overload;
    function Insert(Index: Integer; const S: String): Integer;
    procedure Delete(Index: Integer);
  end;

{ TStringArrayHelper }

constructor TStringArrayHelper.Create(AValue: TStringArray);
begin
  Self := AValue;
end;
function TStringArrayHelper.Insert(Index: Integer; const S: String): Integer;
var
  i: Integer;
begin
  SetLength(Self, Length(Self)+1);
  for i := High(Self) downto (Index + 1) do
    Self[i] := Self[i-1];
  Self[Index] := S;
  Result := Index;
end;
procedure TStringArrayHelper.Delete(Index: Integer);
var
  i: Integer;
begin
  for i := Index to (High(Self) - 1) do
    Self[i] := Self[i+1];
  SetLength(Self, Length(Self) - 1);
end;

{ TStringTable }

function TStringTable.InsertCol(Index: Integer; Values: array of
String): Integer;
var
  i: Integer;
begin
  FRows[0].Insert(Index, '');
  //for i := Low(FRows) to High(FRows) do
  begin
    //if (i <= High(Values)) then
      FRows[i].Insert(Index, Values[i])
    //else
    //  FRows[i].Insert(Index, '');
  end;
  Result := Index;
end;
procedure TStringTable.DeleteCol(Index: Integer);
var
  i: Integer;
begin
  FRows[0].Delete(Index);
end;
end.
======================================

The declaration of the helper is before any location is is used as far as I can see.

thtest.pp(80,12) Fatal: Syntax error, "CREATE" expected but "DELETE" found
Line 80 is:
  FRows[0].Delete(Index);

Why does the compile NOT like FRows[0].Delete(), but does not care about the earlier
(line 69) FRows[i].Insert(Index, Values[i]) ??

Even stranger (to me):

If you uncomment

  //FRows[0].Insert(Index, '');

at line 65, the compiler will see the error at the above mentioned line 69:

thtest.pp(69,16) Fatal: Syntax error, "CREATE" expected but "INSERT" found

But why does it not fail then at the uncommented line that also calls the Insert method?

NB. These are my compiler options:
-MObjFPC -Scghi -Cirot -g -gl -gh -l -vewnhibq -Filib\i386-win32 -Fu. -FUlib\i386-win32 -FcUTF8

Bart

Reply by email

Bart
to Bart
Bart wrote
NB. These are my compiler options: -MObjFPC -Scghi -Cirot -g -gl -gh -l -vewnhibq -Filib\i386-win32 -Fu. -FUlib\i386-win32 -FcUTF8

When I remove the -FcUTF8, compilation succeeds.
This sounds like a bug to me.

B.t.w. I cannot test with fpc trunk.
So, someone should confirm this.

Note that in my first example, after fixing the mistake Sven pointed out, also compiled WITH -FcUTF8.

Bart

Reply by email

Sven Barth
to Bart
"Bart" wrote 9 lines
On 12/31/16, Bart wrote: > NB. These are my compiler options: > -MObjFPC -Scghi -Cirot -g -gl -gh -l -vewnhibq -Filib\i386-win32 -Fu. > -FUlib\i386-win32 -FcUTF8 When I remove the -FcUTF8, compilation succeeds. This sounds like a bug to me.

Could indeed be the case due to codepaged strings being different types. I think there already is a bug report along those lines...

Regards,
Sven

Reply by email

Bart
to Sven Barth: Could indeed be the case due to codepaged strings being different types. I think there…
Sven Barth wrote
Could indeed be the case due to codepaged strings being different types. I think there already is a bug report along those lines...

I just (for the first time ever) built fpc from trunk (r35221) and it compiles the troublesome code just fine.

Now I need to check wether the 3.0.2 RC1 does too. If it is inddeed r33214 that fixed it, I think it is in 3.0 fixes. We'll see (but not today).

PS How can I get the "make install" to generate a fpc.cfg file?

Bart

Reply by email

Bart
to Bart
Bart wrote
Now I need to check wether the 3.0.2 RC1 does too. If it is inddeed r33214 that fixed it, I think it is in 3.0 fixes. We'll see (but not today).

Compiles OK with 3.0.2RC1.

Bart

Reply by email

Sven Barth
"Bart" wrote 12 lines
On 1/1/17, Sven Barth wrote: > Could indeed be the case due to codepaged strings being different types. > I think there already is a bug report along those lines... I just (for the first time ever) built fpc from trunk (r35221) and it compiles the troublesome code just fine. Now I need to check wether the 3.0.2 RC1 does too. If it is inddeed r33214 that fixed it, I think it is in 3.0 fixes. We'll see (but not today).

I knew that the problem sounded familiar ;)

PS How can I get the "make install" to generate a fpc.cfg file?

I think we have a generator for it in utils or so. I've never used it however...

Regards,
Sven

Reply by email

Bart
to Sven Barth
Sven Barth wrote
I knew that the problem sounded familiar ;)

Even better, I opened that ticket, allbeit on behalve of someone else in the forum (Silvio).

> PS How can I get the "make install" to generate a fpc.cfg file? I think we have a generator for it in utils or so. I've never used it however...

I just copied the 3.0 config and did a search and replace on the paths.

Bart

Reply by email

Sven Barth
to Bart
"Bart" wrote 6 lines
>> PS How can I get the "make install" to generate a fpc.cfg file? > > I think we have a generator for it in utils or so. I've never used it > however... I just copied the 3.0 config and did a search and replace on the paths.

That's what I do as well ;)

Regards,
Sven

Reply by email