[fpc-pascal] modeswitch multihelpers precedence problem

Sven Barth pascaldragon at googlemail.com
Tue Mar 10 11:10:56 CET 2020


Michael Van Canneyt <michael at freepascal.org> schrieb am Di., 10. März 2020,
08:11:

>
>
> On Tue, 10 Mar 2020, Anthony Walter via fpc-pascal wrote:
>
> > I started adding {$modeswitch multihelpers} to some of my code and
> noticed
> > a problem. It would seem that the SysUtils unit is defining type helpers
> > for the string type and this led me to discover that multiple type
> helpers
> > takes precedence over other helpers in a way that is conflicts with other
> > pascal rules.
> >
> > To demonstrate, if I have MyUnit.pas that defines a string type helper
> > with EndsWith() and an IntToStr() function then consider the following
> code:
> >
> > program Test;
> >
> > uses
> >  MyUnit, SysUtils;
> >
> > begin
> >  'hello'.EndsWith('lo'); // invokes MyUnit.TStringHelper.EndsWith()
> >  IntToStr(12); // invokes SysUtils.IntToStr()
> > end.
> >
> > But if I reverse the uses order:
> >
> > program Test;
> >
> > uses
> >  SysUtils, MyUnit;
> >
> > begin
> >  'hello'.EndsWith('lo'); // invokes SysUtils.TStringHelper.EndsWith()
> >  IntToStr(12); // invokes MyUnit.IntToStr()
> > end.
> >
> > What should happen is that both examples use the function from the last
> > unit in the uses clause. Using the example above with "uses SysUtils,
> > MyUnit;" the following should happen:
> >
> >  'hello'.EndsWith('lo'); // invokes MyUnit.TStringHelper.EndsWith()
> >  IntToStr(12); // invokes MyUnit.IntToStr()
> >
> > I know some of you might see this as a small problem, but it's an
> > inconstancy that can lead to a situation where the wrong methods will be
> > called without being obvious. The standard has long been that when an
> > identifier of the same name is is found, pascal will choose to identify
> the
> > name as the one coming from the last matching unit in the uses clause.
> > Multiple type helpers should follow this same rule.
>
> I'm inclined to think you found the reason why Embarcadero disallows type
> helpers.
>
> A type helper extends a type with some additional methods. Since the
> sysutils unit comes first in the uses clause, it is the first to extend the
> string type. Then comes the myunit helper, which tries to extend the same
> type with the same methods. The compiler sees the first attached method.
>
> I agree the order of the units is relevant, but I think that it is acting
> more like unit initialization & class constructor order
> (if viewed as 'attaching methods to type') than like identifier scope
> (if viewed as 'looking for method identifier').
>
> So while I agree it may be confusing, it's not necessarily wrong.
>
> I suppose Sven can shed some light on the matter.
>

It should work as with normal identifiers and multiple helpers without the
modeswitch (there the last one wins as well). So this is indeed a bug
(though hopefully easy to solve).

@Anthony: would you report that, please?

Regards,
Sven

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20200310/e7224001/attachment.html>


More information about the fpc-pascal mailing list