Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2025-02

Question on function overloading and pointer types

4 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bart

Hi,

I possibly did not search hard enough, but did not find what the "rules" are regarding overload selection (is that the correct term?).

Consider this simple example:
===
program test;
{$ifdef fpc}
{$mode fpc}
{$endif fpc}
{$apptype console}
{$ifndef fpc}
type
  TProcedure = procedure;
{$endif not pc}
procedure dummyproc;
begin
end;
procedure Foo(buf: pointer); {$ifndef fpc}overload;{$endif not fpc}
begin
  writeln('Foo(buf: pointer)');
end;
procedure foo(proc: TProcedure); {$ifndef fpc}overload;{$endif not fpc}
begin
  writeln('Foo(proc: TProcedure)');
end;
var
  x: integer;
begin
  write('foo(@x) -> ');
  foo(@x);
  write('foo(@dummyproc) -> ');
  foo(@dummyproc);
  write('foo(nil) -> ');
  foo(nil);
end.
====

fpc outputs:
foo(@x) -> Foo(buf: pointer)
foo(@dummyproc) -> Foo(proc: TProcedure)
foo(nil) -> Foo(buf: pointer)

Delphi 7 (yes, very old, probably not a good reference): foo(@x) -> Foo(buf: pointer)
foo(@dummyproc) -> Foo(buf: pointer)
foo(nil) -> Foo(buf: pointer)

So, fpc is more clever than D7.
I would have expected though that foo(nil) would cause a "cannot determine which overload to call" compiler error. (Which in my particular case I would have welcomed.)

Q1: do we have some documentation about this overload selection process? Q2: if not, then is the observed behaviour of current fpc by design or undefined?

Bart

Bart

Reply by email

Tomas Hajny
to Bart

On 2025-02-25 20:04, Bart via fpc-devel wrote:

Hi Bart,

Show quoted text 53 lines
I possibly did not search hard enough, but did not find what the "rules" are regarding overload selection (is that the correct term?). Consider this simple example: === program test; {$ifdef fpc} {$mode fpc} {$endif fpc} {$apptype console} {$ifndef fpc} type TProcedure = procedure; {$endif not pc} procedure dummyproc; begin end; procedure Foo(buf: pointer); {$ifndef fpc}overload;{$endif not fpc} begin writeln('Foo(buf: pointer)'); end; procedure foo(proc: TProcedure); {$ifndef fpc}overload;{$endif not fpc} begin writeln('Foo(proc: TProcedure)'); end; var x: integer; begin write('foo(@x) -> '); foo(@x); write('foo(@dummyproc) -> '); foo(@dummyproc); write('foo(nil) -> '); foo(nil); end. ==== fpc outputs: foo(@x) -> Foo(buf: pointer) foo(@dummyproc) -> Foo(proc: TProcedure) foo(nil) -> Foo(buf: pointer) Delphi 7 (yes, very old, probably not a good reference): foo(@x) -> Foo(buf: pointer) foo(@dummyproc) -> Foo(buf: pointer) foo(nil) -> Foo(buf: pointer) So, fpc is more clever than D7.

.
.

No, it's because you used a different compilation mode _and_ FPC treats @ differently depending on the compilation mode. If you change "{$mode fpc}" to "{$mode delphi}" and make the "overload" directive non-conditional (otherwise FPC rejects to compile the source in that mode), you get the same result with FPC as with your Delphi 7. If you change "foo(@dummyproc)" to "foo(dummyproc)" and recompile it (still with {$mode delphi}), you get the same result as with the original version in {$mode fpc} - I guess that Delphi 7 might give you the same result, but I might be wrong.

Tomas

Reply by email

Bart
to Tomas Hajny
No, it's because you used a different compilation mode _and_ FPC treats @ differently depending on the compilation mode. If you change "{$mode fpc}" to "{$mode delphi}" <snip> I guess that Delphi 7 might give you the same result, but I might be wrong.

(Slaps himself in the face...)

Yeah, right.
Ifdef-ed the @ in @dummyproc for fpc only and D7 outputs the same.

Still leaves my questions though:

Q1: do we have some documentation about this overload selection process? Q2: if not, then is the observed behaviour of current fpc by design or undefined?
Bart

Reply by email

Wayne Sherman
to Bart
Bart wrote
> Q1: do we have some documentation about this overload selection process? > Q2: if not, then is the observed behaviour of current fpc by design or > undefined?

Depending on the mode @variable can return an untyped pointer (@my_integer is type Pointer) or a typed pointer (@my_integer is type ^integer). The compiler uses the type to determine which overloaded procedure to call.

https://www.freepascal.org/docs-html/prog/progsu75.html "In the {$T+} or {$TYPEDADDRESS ON} state, the @ operator, when applied to a variable, returns a result of type ^T, if the type of the variable is T. In the {$T-} state, the result is always an untyped pointer, which is assignment compatible with all other pointer types."

See also:
https://wiki.freepascal.org/Pointer#Data_Type

Reply by email