### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Operator overloading: Someone please explain this  (Read 5185 times)

#### Zvoni

• Sr. Member
• Posts: 373
##### Operator overloading: Someone please explain this
« on: March 18, 2019, 09:07:57 pm »
Hi Folks,

playing around i overloaded some operators
Code: Pascal  [Select][+][-]
1. //Somewhere in a Unit
2. interface
3. //String and LongInt
4. Operator +(AString:String;ALongInt:LongInt):String;Overload;
5. Operator +(ALongInt:LongInt;AString:String):String;Overload;
6.
7. Implementation
8. Operator +(AString:String;ALongInt:LongInt):String;
9. Begin
10.   Result:=AString+ALongInt.ToString;
11. end;
12. Operator +(ALongInt:LongInt;AString:String):String;
13. Begin
14.   Result:=ALongInt.ToString+AString;
15. end;
16.

Using above i stumbled across this:
Code: Pascal  [Select][+][-]
1. Uses MyOperatorUnit;
2. Var
3. MyText:String;
4. MyNumber:Integer;
5.
6. Begin
7. MyText:='Test ';
8. MyNumber:=123456;
9. Writeln(MyText+MyNumber); //Works
10. Writeln(MyNumber+MyText); //Works
11. Writeln(MyNumber+' Test'); //Works
12. Writeln(123456+MyText);  //Works
13. Writeln(MyText+123456);   //Works
14. Writeln('Test '+MyNumber); //Doesn't work?!?!??! --> project1.lpr(19,19) Error: Incompatible types: got "LongInt" expected "AnsiString"
15.
16.

Huh? I'm looking at it, and it doesn't make any sense to me.
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

#### ASerge

• Hero Member
• Posts: 1644
##### Re: Operator overloading: Someone please explain this
« Reply #1 on: March 18, 2019, 09:25:18 pm »
Code: Pascal  [Select][+][-]
1. Writeln('Test '+MyNumber); //Doesn't work?!?!??! --> project1.lpr(19,19) Error: Incompatible types: got "LongInt" expected "AnsiString"
Huh? I'm looking at it, and it doesn't make any sense to me.
A quoted string can be string, UnicodeString, ShortString, PChar, PWideChar and so on. Cast it: string('Test ') +...

#### Thaddy

• Hero Member
• Posts: 10296
##### Re: Operator overloading: Someone please explain this
« Reply #2 on: March 18, 2019, 09:35:35 pm »
The real explanation is adding {\$H+}
I am more like donkey than shrek

#### ASerge

• Hero Member
• Posts: 1644
##### Re: Operator overloading: Someone please explain this
« Reply #3 on: March 18, 2019, 09:40:41 pm »
The real explanation is adding {\$H+}
Check before you advise. The error occurs in {\$H+}
Code: Pascal  [Select][+][-]
1. {\$MODE OBJFPC}
2. {\$APPTYPE CONSOLE}
3. {\$LONGSTRINGS ON}
4.
5. uses SysUtils;
6.
7. operator + (const Left: string; Right: LongInt): string;
8. begin
9.   Result := Left + IntToStr(Right);
10. end;
11.
12. operator + (Left: LongInt; const Right: string): string;
13. begin
14.   Result := IntToStr(Left) + Right;
15. end;
16.
17. var
18.   Text: string = 'text';
19.   Number: LongInt = 123456;
20. begin
21.   Writeln(Text + Number);
22.   Writeln(Number + Text);
23.   Writeln(Number + 'other text');
24.   Writeln(789012 + Text);
25.   Writeln(Text + 789012);
26.   Writeln('else text' + Number); // project1.lpr(26,25) Error: Incompatible types: got "LongInt" expected "AnsiString"
27.   Readln;
28. end.

#### Zvoni

• Sr. Member
• Posts: 373
##### Re: Operator overloading: Someone please explain this
« Reply #4 on: March 18, 2019, 10:37:56 pm »
So what's the Explanation/Solution?
You lost me along the way there....
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

#### howardpc

• Hero Member
• Posts: 3490
##### Re: Operator overloading: Someone please explain this
« Reply #5 on: March 18, 2019, 10:51:28 pm »
ASerge already explained.
A string constant could be, for example, a PChar.
Because of the plethora of string types FPC supports, the compiler cannot know unambiguously what the type of
Code: Pascal  [Select][+][-]
1.  'some string constant'
might be.
Casting the constant to a String, allows the compiler to see that it is indeed compatible with the String declaration of the parameter in your overloaded operator function.

#### Zvoni

• Sr. Member
• Posts: 373
##### Re: Operator overloading: Someone please explain this
« Reply #6 on: March 18, 2019, 10:59:00 pm »
ASerge already explained.
A string constant could be, for example, a PChar.
Because of the plethora of string types FPC supports, the compiler cannot know unambiguously what the type of
Code: Pascal  [Select][+][-]
1.  'some string constant'
might be.
Casting the constant to a String, allows the compiler to see that it is indeed compatible with the String declaration of the parameter in your overloaded operator function.

????
Then the Error-Message doesn't make sense one jot at all. I was looking at the Integer the whole time, while my String-Literal was at fault.
The Error marked the Integer-Variable to boot!
And it doesn't explain why my Line 11/Serge's Line23 works.....

Or is it because that very first argument is that ambiguous Literal?
Because going by that logic, something like
Writeln('Text1 '+' Text2');
shouldn't work, which it does;
Oh, and FWIW: I stumbled across that not by using Writeln, but passing a String to a Function/Procedure which expects a String
« Last Edit: March 18, 2019, 11:02:30 pm by Zvoni »
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

#### Zvoni

• Sr. Member
• Posts: 373
##### Re: Operator overloading: Someone please explain this
« Reply #7 on: March 18, 2019, 11:13:41 pm »
After fiddling around a bit more, i'm still not satisfied with the proposed Answer!

For grins i did a

Code: Pascal  [Select][+][-]
1. Var
2. b:Boolean;
3.
4. Begin
5. Writeln('Test '+b);
6.

How is it, that the compiler throws the error
project1.lpr(7,18) Error: Operator is not overloaded: "Constant String" + "Boolean"

Constant String against Boolean.
So, the compiler recognizes it as a Constant String.
If i overload the "+"-Operator in a String/Boolean and Boolean/String-Combination, all combinations pass, even those with Literals

Writeln('This '+True);                  //Works!

EDIT:
Everything in
{\$mode objfpc}{\$H+}

EDIT: OH NONONO
I Reject the Answer.
I just did the same Test as in my first Post, but with Double instead of Integer. It worked in all combinations!
So no, i don't believe it's the "Constant string" and the Error-Message is correct. It's the Integer!

EDIT3:
There is something wrong. I just commented out my operator unit (to force error-messages)
In the combination in question it's still the same error-message, so the error occurs before checking if an (overloaded) operator is available
« Last Edit: March 18, 2019, 11:24:41 pm by Zvoni »
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

#### howardpc

• Hero Member
• Posts: 3490
##### Re: Operator overloading: Someone please explain this
« Reply #8 on: March 19, 2019, 01:26:21 am »
You are correct.
The compiler appears to treat a constant string in combination with other types differently if the other type is any kind of integer.
It seems to get stuck at its own internal concatenation attempt, and fails to consider the correctly declared overloaded operator alternative.

#### Zvoni

• Sr. Member
• Posts: 373
##### Re: Operator overloading: Someone please explain this
« Reply #9 on: March 19, 2019, 06:33:25 am »
You are correct.
The compiler appears to treat a constant string in combination with other types differently if the other type is any kind of integer.
It seems to get stuck at its own internal concatenation attempt, and fails to consider the correctly declared overloaded operator alternative.
Conclusion: Bug?
Considering a boolean (see above) is basically an integer
« Last Edit: March 19, 2019, 06:36:03 am by Zvoni »
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

#### Thaddy

• Hero Member
• Posts: 10296
##### Re: Operator overloading: Someone please explain this
« Reply #10 on: March 19, 2019, 09:25:20 am »
Yes, it is a bug, and for all supported string types the same bug. Same happens in shortstring, ansistring and unicodestring modes.
Just to be sure I also tested if sysutils could have some influence (because it contains some overloads?), but that is not the case.
Here's my reduced example:
Code: Pascal  [Select][+][-]
1. {\$MODE OBJFPC}
2. {\$IFDEF MSWINDOWS}{\$APPTYPE CONSOLE}{\$ENDIF}
3.
4. operator + (Left: LongInt; const Right: string): string;
5. begin
6.   writestr(Result,Left,Right);
7. end;
8.
9. operator + (const Left: string; Right: LongInt): string;
10. begin
11.   writestr(Result,Left,Right);
12. end;
13.
14. var
15.   Text: string = 'text';
16.   Number: LongInt = 123456;
17. begin
18.   Writeln(Text + Number); // V+V
19.   Writeln(Number + Text); // V+V
20.   Writeln(789012 + Text);//L+V
21.   Writeln(Text+789012);//V+L
22.   // Next fails and is L+V
23.   Writeln('else text'+Number); // fails only on LEFT string literals + non-literal number with all string types
24.   // Next pass again
25.   Writeln(Number + 'other text'); // passes, V+L
26.   Writeln(string('else text')+Number); //passes, cast(L)+V
27.   writeln(789012 + 'other text'); // passes, L+L
28.   writeln('other text',789012); // passes, L+L
29.   Readln;
30.   Readln;
31. end.
As you can see I have added some more - missing- tests from which one can conclude that this is the exact issue:
The overloaded operator fails only on LEFT string literals + non-literal number with all string types.
All other possible cases pass.
« Last Edit: March 19, 2019, 10:54:11 am by Thaddy »
I am more like donkey than shrek

#### Zvoni

• Sr. Member
• Posts: 373
##### Re: Operator overloading: Someone please explain this
« Reply #11 on: March 19, 2019, 11:35:34 am »
Someone going to report that bug?
I've never done that

EDIT: Thaddy, your last Test is not of the same variety. You use Writeln String-Literal COMMA LiteralInteger.
You're passing 2 Arguments to Writeln instead of one

writeln('Test'+123456);
This one fails too with the same errormessage
« Last Edit: March 19, 2019, 11:40:23 am by Zvoni »
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

#### Thaddy

• Hero Member
• Posts: 10296
##### Re: Operator overloading: Someone please explain this
« Reply #12 on: March 19, 2019, 11:37:06 am »
I will do that now.
I am more like donkey than shrek

#### Zvoni

• Sr. Member
• Posts: 373
##### Re: Operator overloading: Someone please explain this
« Reply #13 on: March 19, 2019, 11:40:34 am »
See my edit
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

#### Thaddy

• Hero Member
• Posts: 10296
##### Re: Operator overloading: Someone please explain this
« Reply #14 on: March 19, 2019, 12:17:36 pm »
Mm. call it a typo. Corrected.
I am more like donkey than shrek