XE3 vs. XE5: Changes in TPointF.Create (System.Types.pas) broke my code:

XE3 vs. XE5: Changes in TPointF.Create (System.Types.pas) broke my code:

XE3-Version:

constructor TPointF.Create(const X, Y: Single);
begin
  Self.X := X;
  Self.Y := Y;
end;

XE5-Version:

class function TPointF.Create(const AX, AY: Single): TPointF;
begin
  Result.X := AX;
  Result.Y := AY;
end;

Do you see the difference?

Now my Code:

var P: TPointF;
P.Create(10, 5);

I now have to find all those places and replace it with

P := TPointF.Create(...);

I hope I don't miss any occurrence.

Comments

  1. Record constructor syntax was bad IMHO, class function makes more sense (no ambiguity between function & procedure, non-mutating and mutating, and while mentioning it, you shouldn't be allowed to invoke a constructor on an instance outside of a constructor, that goes for objects as well)

    I wish they had used record constructors to provide custom default record initialization instead. This would have allowed you to have a record where even non-managed fields are initialized (and the destructor could then have a similar purpose for finalization)

    There have been several QCs from way back on allowing to specify custom record initialization/finalization code...

    ReplyDelete
  2. I have the same opinion, the constructor for the record - it is evil. Yes, this is a syntax sugar, but not clear to read of code source

    ReplyDelete
  3. I know this was bad style...but it seemed the fasted way to set those two values. P := TPoint.Create(...) allocates some memory for the extra record which I wanted to avoid.

    ReplyDelete
  4. To set the variable, rather than piggyback the constructor, you could just have declared a SetXY() or Init() or whatever method (same body as you Create). This would have had the same performance and made it obvious you were setting/initializing the record.

    ReplyDelete
  5. Eric Grange Such a method should exist in TPointF and it does indeed, called SetLocation...but it's marked as deprecated in XE5 with no suiteable replacement.
    You are right that it's easy to build a simple (even inlineable) procedure but then it's not inside the TPointF namespace anymore.

    ReplyDelete
  6. Ouch. Though TBH, they really messed the record methods by allowing them to bypass the "const" qualifier and mutate everything (even global constants), and that's coming home to roost. But they're fixing it the wrong way.
    (http://www.delphitools.info/2012/05/07/mutant-records-on-methods-and-helpers/)

    ReplyDelete
  7. Having spent some time in C++ I really miss the C++ const semantics.

    ReplyDelete

Post a Comment