Sign in Join

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

Mailing lists / fpc-devel / 2019-04

Operator overloading

5 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,

Forgive me for the long introduction before I ask the question. It is the first time I try to fix a possible error in the compiler itself.

I was delving into https://bugs.freepascal.org/view.php?id=29460 It is impossible to overload = operator for longint = string.

Sample code:
program op;
{$mode objfpc}
{$h+}
operator = (L: Integer; R: String) z: Boolean;
begin
end;
begin
end.
Gives: op.lpr(6,46) Error: Impossible operator overload

I tracked it down to this piece of code on htypechk.pas

in function isbinaryoperatoroverloadable
in the nested function internal_check
this block of code:

case ld.typ of (ld.typ=orddef in this case)
....

orddef, floatdef:

  begin
    allowed:=not (
     (
       (rd.typ in [orddef,floatdef]) and
       (treetyp in order_theoretic_operators)
     ) or
     (
       is_stringlike(rd) and  //<< this block of code forbids it
       (ld.typ=orddef) and
       (treetyp in string_comparison_operators)) or
       { c.f. $(source)\tests\tmacpas5.pp }
       (
         (rd.typ=setdef) and
         (ld.typ=orddef) and
         (treetyp in element_set_operators)
       )
      { This clause may be too restrictive---not all types under
        orddef have a corresponding set type; despite this the
        restriction should be very unlikely to become
        a practical obstacle, and can be relaxed by simply
        adding an extra check on TOrdDef(rd).ordtype }
     );

In MacPas mode you can compare an ordinal to a string (but only with the ordinal on the left).
See tests/test/tmacpas5.pp for an example.

I added a check for MacPas mode, only forbidding this operator overload for that mode.
(Patch is in the bugtracker)
This seems to resolve the original issue.

Then I tried to compile the example in MacPas mode, expecting it to
give "op.lpr(6,46) Error: Impossible operator overload" error.
Instead it gave: op.lpr(6,9) Fatal: Syntax error, "BEGIN" expected but
"identifier OPERATOR" found.

Naturally I though my patch caused this, but 3.0.4 gives exactly the same error message.

This raises for me the following questions:

1.
Is operator overloading possible at all in MacPas mode (does it need some modeswitch)?

2.
If this is not the case, then why forbid this particular operator overload at all?

Bart

Reply by email

Jonas Maebe
to Bart: Forgive me for the long introduction before I ask the question. It is the first time I…
Bart wrote
1. Is operator overloading possible at all in MacPas mode (does it need some modeswitch)?

It's not possible.

2. If this is not the case, then why forbid this particular operator overload at all?

You can use a unit that is compiled in e.g. mode ObjFPC in a unit compiled in MacPas mode, and then the latter will use the overloaded operators from the former.

Jonas

Reply by email

Bart
to Jonas Maebe
PM Jonas Maebe wrote
It's not possible.

OK.

You can use a unit that is compiled in e.g. mode ObjFPC in a unit compiled in MacPas mode, and then the latter will use the overloaded operators from the former.

So, allowing it in other modes cannot be permitted because of this?

Bart

Reply by email

Bart
to Bart
program op;
uses opovr;
procedure test;
var
  d: dword;
begin
  d:=(65 shl 24) or (66 shl 16) or (67 shl 8) or 68;
  if (d'ABCD') then
    writeln('d  "ABCD"')
  else
    writeln('d = "ABCD"');
end;
begin
  test;
end.
unit opovr;
{$mode objfpc}
{$H+}
interface
operator = (L: dword; R: String) z: Boolean;
implementation
operator = (L: dword; R: String) z: Boolean;
begin
  z:=False;
end;
end.

After applying the patch from the bugtracker:

C:\Users\Bart\LazarusProjecten\bugs\Console\operator>fpc op.lpr -Mobjfpc -B Free Pascal Compiler version 3.3.1 [2019/04/03] for i386 ...
46 lines compiled, 0.1 sec, 35712 bytes code, 1316 bytes data

C:\Users\Bart\LazarusProjecten\bugs\Console\operator>op d "ABCD" // operator overload from opovr.pp is used

C:\Users\Bart\LazarusProjecten\bugs\Console\operator>fpc op.lpr -Mmacpas Free Pascal Compiler version 3.3.1 [2019/04/03] for i386 ..
27 lines compiled, 0.2 sec, 79968 bytes code, 4244 bytes data

C:\Users\Bart\LazarusProjecten\bugs\Console\operator>op d = "ABCD" // operator overload from opovr.pp is NOT used (you are allowed to compare ordinal=string in MacPas mode by default)

C:\Users\Bart\LazarusProjecten\bugs\Console\operator>fpc op.lpr -Mmacpas -B Free Pascal Compiler version 3.3.1 [2019/04/03] for i386 Copyright (c) 1993-2018 by Florian Klaempfl and others Target OS: Win32 for i386
Compiling op.lpr
Compiling opovr.pp
opovr.pp(3,2) Error: Mode switch "OBJFPC" not allowed here opovr.pp(8,1) Fatal: There were 1 errors compiling module, stopping Fatal: Compilation aborted

-Mmacpas disallows {$mode objfpc} in another unit?

Conclusion:
If you override the operator in a unit then that overload is NOT used in a program that is built in MacPas mode (as long as the program uses the ppu and does not try to rebuild the unit from source).

If that conclusion is correct, then the patch could be applied? Or are there more caveats?

B.t.w. to my surprise it seems you cannot overload the = operator in the opovr.pp unit if that unit uses {$mode Delphi}: opovr.pp(8,1) Fatal: Syntax error, "IMPLEMENTATION" expected but "identifier OPERATOR" found.

Bart

Reply by email