Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Bob Swart (aka Drs.Bob) Dr.Bob's Delphi Clinics Dr.Bob's Delphi Courseware Manuals
View Bob Swart's profile on LinkedIn Drs.Bob's Delphi Notes
These are the voyages using Delphi Enterprise (and Architect). Its mission: to explore strange, new worlds. To design and build new applications. To boldly go...
Title:

Weekend "with" fun - extreme corner case

Author: Bob Swart
Posted: 2/19/2010 5:38:31 PM (GMT+1)
Content:

While migrating source code of a client of mine from an older version of Delphi to Delphi 2010, I encountered a compiler Error: E2064 Left side cannot be assigned to in some strange places, that turned out to be a truly "extreme corner cases" of with-usage.

Pop-quizz... what's wrong with this little program:

  program WithBUG;
uses
Windows;
var
Pal: TPaletteEntry;
begin
with
(Pal) do
begin

peRed := 42;
peGreen := 42;
peBlue := 42;
peFlags := PC_NOCOLLAPSE
end
end
.
The Delphi 2010 compiler gives the aforementioned error no less than four times; for each of the peXXX field assignments. The problem is caused by the brackets around the "Pal" inside the "with" statement. Without brackets, with works fine. With brackets, we get the error message.

Extreme corner case, but fun to report anyway, see QC #82301.

Have a nice weekend! ;-)

Back  


15 Comments

AuthorPostedComments
Rich 10/02/19 19:13:26In some countries like USA, '(' and ')' are called parenthesis, while '[' and ']' are called brackets.
Bob Swart 10/02/19 19:48:26Oops! Sorry about the bracket <-> parenthesis mixup. FWIW, it also doesn't compile if you use [] ;-)
Erik 10/02/19 19:52:35The compiler should also give the error when no parenthesis are used. Because "with" is evil ;-) Happy weekend to you too!
alex 10/02/19 20:49:01(Pal) is treated as an expression and expressions are "read-only" in with.
Bob Swart 10/02/19 21:22:20But "with (Pal) do" compiles just fine with old(er) versions of Delphi... I've seen several units today that use this syntax, and compiled just fine with delphi 7 and 2005, but gave compiler errors with Delphi 2010.
Arvid 10/02/19 22:07:29Not related to with: Just doing a (Pal).peRed := 42; doesn't compile either. Probably best to extend the QC report as it's related to the Records itself.
Bob Swart 10/02/19 22:10:42Ouch, good catch. I'll update the QC report indeed...
Bob Swart 10/02/19 22:13:44No use - it's marked as a duplicate report of QC #81701, and has been closed.
Resolution: As Designed
François 10/02/19 22:22:22... and the QC status is "as-designed" ! Seems they corrected an old but deemed incorrect behavior....
Bob Swart 10/02/19 22:25:37Unfortunately, this "fix" seems to break some existing code, which won't show until you try to migrate the source code to Delphi 2010 (although it may have been introduced in 2009 or earlier - I just noticed it when migrating code from Delphi 7-2005 to 2010). Fortunately, it's not hard to fix it, once you know what to look for. But it had me puzzled for a little while...
Uwe 10/02/19 22:35:00I am puzzled because the given example did never compile, but similar code with a class instead of a record compiled till D2009. The behavior is as designed and I am that evil guy that has closed your report shortly after you've filed it. The parenthesis creates a non-writable rvalue and in general D2010 is stricter and disallows for example writing of readonly properties with "with", which was possible till D2009.
Bob Swart 10/02/19 23:28:33The following compiles with Delphi 7, but not with Delphi 2010:
program WithBUG;
uses
  Windows;
type
  TMyPal = class
    Pal: TPaletteEntry;
  end;
var
  X: TMyPal;
begin
  X := TMyPal.Create;
  with (X.Pal) do
  begin
    peRed := 42;
    peGreen := 42;
    peBlue := 42;
    peFlags := PC_NOCOLLAPSE
  end
end.
And I don't consider you evil for closing my report ;-)
Oliver 10/02/20 16:21:23I assume the TPaletteEntry in your example is a class type rather than a record? Otherwise this also wouldn't have compiled in earlier versions of Delphi. When using parens around record-type (or more generally value-type?) variables in a with-statement these have always been treated as read-only.
Gerry 10/02/21 23:58:47Just confirmed that D2009 does this as well
DelfiPhan 10/02/25 16:05:11I wish they'd finally fix WITH. It displays variables in the ROOT with the same name! In the DOS days, the debugger at least would say "cannot access this variable". And as to it being evil, it is in fact a good way of managing complexity and is one of the things that puts Delphi above other languages.


New Comment (max. 2048 characters, no HTML):

Name:
Comment:



This webpage © 2005-2019 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.