[fpc-pascal] with statement using mulltiple objects
johanns at nacs.net
johanns at nacs.net
Mon Sep 15 16:42:28 CEST 2014
On Sun, Sep 14, 2014 at 02:30:01PM +0200, Marco van de Voort wrote:
>In our previous episode, J?rgen Hestermann said:
>> > ---------------------------------------------------------
>> > d:=TreeRoot.SubDirs[Low(TreeRoot.SubDirs)]; // local var d
>> > d^.DirLogged := true;
>> > d^.DirHatFocus := false;
>> > d^.SubDirsExpanded := true;
>> > [...] ---------------------------------------------------------
>>
>>
>> Long-winded and still not the same clarity as in the with statement.
>
>But the important part is that it forces each property/field to be a member
>of T, or get a compiler error.
>
>WITH doesn't, and you risk that if your class or one of its ancestor has
>such property, and your error goes unnoticed.
I have to believe the WITH statement is more efficient
than the C language equivalent where an extra
convenience pointer is declared as a variable and
allocated. The WITH statement allows the compiler to
generate the same code as a fully qualified variable name
without extra overhead in the form of a dummy pointer.
Just as the GOTO statement needs to be used with careful,
close locality of scope, the WITH statement should be used
when the fields will all come from the same record
definition and ideally have distinct names. The safe
approach would be to qualify all field references that are
potentially ambiguous even while using a WITH statement.
The danger of surprises in scope evaluation for a simple
and short variable name within a WITH statement scope are
not that different from the danger of unit global
variables. Each unit creates its own local name space,
which usually does the programmer a favor, but not always.
Now the order units are referenced in the USES statement
of each individual unit matters. What do you think
happens when the programmer is casual about the USES order
for helper utility units with duplicate global variable
names?
Unit FooUtil1;
var ErrorString : string;
Unit BarUtil2
var ErrorString : string;
Unit CodeSection;
uses FooUtil1, BarUtil1;
procedure Main
begin
ErrorString := ''; {Clears error string in last unit}
.
.
end;
More information about the fpc-pascal
mailing list