Recent

Author Topic: Overloaded function not working in objfpc ?  (Read 674 times)

Nitorami

  • Sr. Member
  • ****
  • Posts: 378
Overloaded function not working in objfpc ?
« on: August 01, 2020, 09:50:46 am »
What is going on here ? Instead of zero I get a random result. The first version of testme is never called.  The compiler seems to interpret testme as a variable rather than a function call !?!

It works in mode delphi which forces me to declare both versions as overloaded. But not in objfpc. FPC 3.2.0, win32, no optimisations.

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2.  
  3. function testme: dword;
  4. begin
  5.   writeln ('Version 1 called');
  6.   result := 0;
  7. end;
  8.  
  9. function testme (range: dword): dword; overload;
  10. begin
  11.   writeln ('Version 2 called');
  12.   result := testme mod range;
  13. end;
  14.  
  15. begin
  16.  writeln (testme (1000));  //prints some random number
  17. end.
  18.  

process_1

  • Guest
Re: Overloaded function not working in objfpc ?
« Reply #1 on: August 01, 2020, 09:52:32 am »
You have to place overload to both functions:

Code: Pascal  [Select][+][-]
  1. function testme: dword; overload;
  2. function testme (range: dword): dword; overload;
  3.  

TRon

  • Sr. Member
  • ****
  • Posts: 423
Re: Overloaded function not working in objfpc ?
« Reply #2 on: August 01, 2020, 09:58:36 am »
The compiler seems to interpret testme as a variable rather than a function call !?!
That is because it does. It is the function name and thus the result value.

Code: Pascal  [Select][+][-]
  1. result := testme() mod range;
  2.  
Should actually invoke the function for you.

process_1

  • Guest
Re: Overloaded function not working in objfpc ?
« Reply #3 on: August 01, 2020, 10:00:49 am »
BTW, in this case better use default parameter values, as this :

Code: Pascal  [Select][+][-]
  1. function testme (range: dword=0): dword;
  2.  

And then adopt function itself. Then no need for overloaded functions.
« Last Edit: August 01, 2020, 10:05:46 am by process_1 »

Thaddy

  • Hero Member
  • *****
  • Posts: 10293
Re: Overloaded function not working in objfpc ?
« Reply #4 on: August 01, 2020, 10:10:26 am »
Your code works as expected here on my Raspbians (both 32 and the experimental AARCH64)
I am more like donkey than shrek

Nitorami

  • Sr. Member
  • ****
  • Posts: 378
Re: Overloaded function not working in objfpc ?
« Reply #5 on: August 01, 2020, 10:16:20 am »
Thanks for the quick responses.

@process_1:
- declaring both as overload does not help in mode objfpc.
- the code is just a sample I made to demonetrate the effect. In the full code, I cannot use a default parameter.

@TRon:
Understood. "testme" is also the function result as it used to be in Turbo Pascal days. It does work as intented when using the brackets testme(). But that is nasty and a source of error, as Pascal does not normally enforce the explicit use of empty brackets....

@Thaddy: Alright, bot not on windows. The compiler interprets the function name as result, rather than the previously declared function.

TRon

  • Sr. Member
  • ****
  • Posts: 423
Re: Overloaded function not working in objfpc ?
« Reply #6 on: August 01, 2020, 10:17:18 am »
Hint 1:
Code: [Select]
fpc -V3.2.0 -B "callingout.pas" (in directory: /home/tron/projects/assorted)
Free Pascal Compiler version 3.2.0 [2020/06/08] for arm
Copyright (c) 1993-2020 by Florian Klaempfl and others
Target OS: Linux for ARMHF
Compiling callingout.pas
callingout.pas(14,20) Warning: Function result variable does not seem to be initialized
Linking callingout
19 lines compiled, 0.6 sec
1 warning(s) issued
Compilation finished successfully.

Hint 2:
Code: [Select]
./callingout
Version 2 called
680

fixed:
Code: [Select]
fpc -V3.2.0 -B "callingout.pas" (in directory: /home/tron/projects/assorted)
Free Pascal Compiler version 3.2.0 [2020/06/08] for arm
Copyright (c) 1993-2020 by Florian Klaempfl and others
Target OS: Linux for ARMHF
Compiling callingout.pas
Linking callingout
19 lines compiled, 0.5 sec
Compilation finished successfully.

Code: [Select]
./callingout
Version 2 called
Version 1 called
0

edit:
Code: [Select]
$ uname -a
Linux raspberrypi 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv7l GNU/Linux

Code: [Select]
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
VERSION_CODENAME=stretch
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

Code: [Select]
$ cat /proc/device-tree/model
Raspberry Pi 3 Model B Plus Rev 1.3
« Last Edit: August 01, 2020, 11:50:05 am by TRon »

TRon

  • Sr. Member
  • ****
  • Posts: 423
Re: Overloaded function not working in objfpc ?
« Reply #7 on: August 01, 2020, 10:21:18 am »
@TRon:
Understood. "testme" is also the function result as it used to be in Turbo Pascal days. It does work as intented when using the brackets testme(). But that is nasty and a source of error, as Pascal does not normally enforce the explicit use of empty brackets....
It is actually pretty normal for FPC. But as usual, i'm unable to locate the right page of documentation so quickly  :-[

edit: I was finally able to find it mentioned in the documentation ... https://www.freepascal.org/docs-html/current/ref/refse81.html#x143-16500012.2
Quote
Sometimes, the call is desired, for instance in recursion in that case, the call must be forced. This can be done by adding the parenthesis to the function name:

Not sure if it is explained in more detail somewhere else (I seem to remember it does, no idea where though).
« Last Edit: August 01, 2020, 10:33:34 am by TRon »

PascalDragon

  • Hero Member
  • *****
  • Posts: 1958
  • Compiler Developer
Re: Overloaded function not working in objfpc ?
« Reply #8 on: August 01, 2020, 10:33:17 am »
@TRon:
Understood. "testme" is also the function result as it used to be in Turbo Pascal days. It does work as intented when using the brackets testme(). But that is nasty and a source of error, as Pascal does not normally enforce the explicit use of empty brackets....

This is one of the point where FPC's original heritage of TP shows (instead of being solely based on Delphi). Overloading was only added with Delphi and thus to “merge” the two concept of result names and overloads for FPC it was decided to go this way, so that one can keep using the named result variable even if overloads are in play. And in 99% of the cases this isn't a problem.

@Thaddy: Alright, bot not on windows. The compiler interprets the function name as result, rather than the previously declared function.

As this behavior is not platform specific I assume that Thaddy did something incorrectly...

process_1

  • Guest
Re: Overloaded function not working in objfpc ?
« Reply #9 on: August 01, 2020, 10:49:05 am »
Try to set your test in delphi mode and you will see the difference and what TRon pointed.

Notice overload keyword is mandatory in delphi mode, in objfpc is ignored and assumed by default.

Calling function in delphi mode without brackets is allowed, in objfpc is completely different.

PascalDragon

  • Hero Member
  • *****
  • Posts: 1958
  • Compiler Developer
Re: Overloaded function not working in objfpc ?
« Reply #10 on: August 01, 2020, 10:54:55 am »
Calling function in delphi mode without brackets is allowed, in objfpc is completely different.

You can also in general call functions in non-Delphi modes without brackets.

There are only two cases where brackets are required:
1. If you have a function A then its result variable is also named A (in addition to Result in modes ObjFPC and Delphi). You can assign to this variable and you can also read from it. Now if you are inside function A and there is a variant of A that has no arguments (it can be the same function or an overload) then there are two possibilites that can be done if A is inside an expression: read the variable or call the function. Delphi calls the function, but FPC reads the variable, except if you use round brackets and thus mark it as a call.

2. If you have a procedure variable it is used to decide whether you read the value of the procedure variable or you call the procedure variable (especially important if the procedure variable is for a function).

Nitorami

  • Sr. Member
  • ****
  • Posts: 378
Re: Overloaded function not working in objfpc ?
« Reply #11 on: August 01, 2020, 11:22:19 am »
Using the function name as result variable was maybe one of Borland's poorer design decisions. Or does that go back to Wirth ?

I remember in TP days how I was always annoyed having to re-type the function name in the function body; why ? Whenever you changed a function name you had to repeat this in the function body.
But well, that was the way to go and I was not aware of anything better until I found in FPC this can be done by result variable, or the exit procedure. This seems to clear and obvious that it makes me wonder how and why it was designed differently in the first place.

Thaddy

  • Hero Member
  • *****
  • Posts: 10293
Re: Overloaded function not working in objfpc ?
« Reply #12 on: August 01, 2020, 11:24:07 am »
As this behavior is not platform specific I assume that Thaddy did something incorrectly...
Nope:
Code: Pascal  [Select][+][-]
  1. program untitled;
  2. {$mode objfpc}
  3.  
  4. function testme: dword;
  5. begin
  6.   writeln ('Version 1 called');
  7.   result := 0;
  8. end;
  9.  
  10. function testme (range: dword): dword;overload;
  11. begin
  12.   writeln ('Version 2 called');
  13.   result := testme mod range;
  14. end;
  15.  
  16. begin
  17.  writeln (testme (1000));  //prints some random number
  18. end.
Outputs:
Code: Bash  [Select][+][-]
  1. Version 2 called
  2. 0
  3.  
on Raspbian and on both architectures (armhf and aarch). I rest my plea..

(If you do not have a Raspberry Pi I can give you one (RPi3) for free)
« Last Edit: August 01, 2020, 11:27:44 am by Thaddy »
I am more like donkey than shrek

process_1

  • Guest
Re: Overloaded function not working in objfpc ?
« Reply #13 on: August 01, 2020, 11:37:07 am »
Using the function name as result variable was maybe one of Borland's poorer design decisions. Or does that go back to Wirth ?

I believe it is Wirth's decision, Borland introduced Result for functions. But not 100% certain in both.

When I started to convert my projects from Delphi to Lazarus there was no converter. In every source file I placed {$mode delphi}. Nowadays, when start new project in Lazarus I do not do that, as I'm aware of the differences between modes.

Also FPC support some C/C++ programming styles by default, as work with C/C++ operators, which is done to make things easier for compilation/optimization and/or code simplicity, but anyway, who would like to stick with puritane delphi syntax - always can.
« Last Edit: August 01, 2020, 11:52:09 am by process_1 »

Nitorami

  • Sr. Member
  • ****
  • Posts: 378
Re: Overloaded function not working in objfpc ?
« Reply #14 on: August 01, 2020, 11:57:40 am »
I myself started learning FPC in mode obj_fpc and got used to it, so use it by default. Coming from TP, objfpc was the obvious choice.
The issue here was an unpleasant surprise which makes me think about changing to Delphi mode. On the other hand, Delphi has made a few very unfortunate design decisions as well. The dumbest idea in my view was to sacrifice the + operator to concat arrays.... a completely unncessary feature, and makes mathematical operators on arrays unusable. It is disabled by default in objfpc, and I appreciate that.

@Thaddy: That is the same behaviour as on win32. Your result is zero but this may still be randomly; the gist is that Version 1 of testme, which would force the result to zero, is never called.

 

TinyPortal © 2005-2018