[fpc-pascal] commutative operators

David Emerson dle3ab at angelbase.com
Thu Dec 30 23:18:12 CET 2010


Mark Morgan Lloyd wrote:
> Can I have a reality check on this please: in this context is the 
> overloaded := effectively an implicit cast as well as an explicit operator?

looks like. Below is some sample code which illustrates the fact.

> Is the availability of overloaded + and := operators necessary and 
> sufficient for += to work correctly?

looks like. also illustrated below.

From the documentation, in reference to C-style += operators: "Remark: These 
constructions are just for typing convenience, they don’t generate different 
code."
In other words, a += b; is equivalent to a := a + b. So indeed, := and + are the 
requirements for +=
At least that's what I gather from the documentation, and the test program 
below.

Using fpc 2.4.2

Warning: for mathematical purists, these operators are absurd. However, they are 
illustrative. Enjoy.


{$mode objfpc}

type
  ta = record
    a : longint;
    end;
  tb = record
    b : longint;
    end;

operator := (a : ta) : tb;
  begin
    result.b := a.a+1;
  end;

operator := (b : tb) : ta;
  begin
    result.a := b.b+10;
  end;

operator + (a, aa : ta) : ta;
  begin
    result.a := a.a + aa.a;
  end;

operator + (a : ta; x : longint) : ta;
  begin
    result.a := a.a + x;
  end;


const
  spc = '  ###  ';

var
  a : ta;
  b : tb;

procedure write_before_op (true_for_a : boolean);
  begin
    if true_for_a
      then write ('a=', a.a, spc)
      else write ('b=', b.b, spc);
  end;

procedure write_after_op (s : string; true_for_a : boolean);
  begin
    write (s, spc);
    if true_for_a
      then writeln ('a=', a.a)
      else writeln ('b=', b.b);
  end;

begin
  a.a := 2;
  writeln ('a.a := 2');

  write_before_op (true);
  a += 1;
  write_after_op ('a += 1', true);  // 3

  write_before_op (true);
  a += a;
  write_after_op ('a += a', true);  // 6

  write_before_op (true);
  writeln ('tb(a).b=', tb(a).b);  // 7

  write_before_op (true);
  b := a;
  write_after_op ('b := a', false);  // 7

  write_before_op (false);
  a := b;
  write_after_op ('a := b', true);  // 17

  b.b := 1;
  writeln ('b.b := 1');
  write_before_op (false);
  a := b + b;  // each b must be typecast to ta, thus adding 10.
  write_after_op ('a := b + b', true);  // 22

  write_before_op (false);
  b := b + b;  // as above, but typecasting the result to tb adds another 1
  write_after_op ('b := b + b', false);  // 23
end.




More information about the fpc-pascal mailing list