Lazarus

Free Pascal => FPC development => Topic started by: EganSolo on October 18, 2017, 02:33:05 am

Title: Difference between += and := -- Is this a bug in FPC?
Post by: EganSolo on October 18, 2017, 02:33:05 am
Before I get ahead of myself and post this as a bug, I thought I would ask here first.
Consider line 8 in the code fragment below: The code uses +=, whereas the commented assignment on line nine  uses :=
When I run the code as is (with +=) and the boolean variable, EmptyStr on line seven is true, the debugger exits the method as if the code on lines eight and ten does not exist. But when I comment that line and uncomment line nine, then the code functions properly.

Am I simply misusing +=? I mean CurrentString is a variable passed to method where this code is implemented and MIF_EmtyCharStyleMarker is a constant declared in another unit.
 
Code: Pascal  [Select]
  1.           Case WordHTMLTag of
  2.             wht_Italics : CurrentString += MIF_ItalicMarker;
  3.             wht_Bold    : CurrentString += MIF_BoldMarker  ;
  4.             wht_span    : If IsOpeningTag
  5.                           then begin
  6.                             EmptyStr := HtmlClass = '';
  7.                             If EmptyStr then
  8.                                CurrentString += MIF_EmptyCharStyleMarker
  9.                            // CurrentString := CurrentString + MIF_EmptyCharStyleMarker
  10.                             else MIF_AddStartCharaTag(HTMLClass)
  11.                           end
  12.                           else If MIF_HasIllegalMarker(CurrentString)
  13.                                then CurrentString += MIF_EmptyCharStyleMarker
  14.                                else MIF_AddEndCharaTag;
  15.             else Assert(False, 'we should not bere here!');
  16.            end;
  17.  
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Blaazen on October 18, 2017, 03:22:33 am
Code: Pascal  [Select]
  1.     CurrentString += MIF_EmptyCharStyleMarker
  2.     CurrentString := CurrentString + MIF_EmptyCharStyleMarker
These two lines are identical. There must be something wrong elsewhere out of pasted code.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 04:19:14 am
You are not misusing += but it is C-style. I never use that style, but from the manual I find that you must use the compiler directive {$COPERATORS ON} to support it.

With a similar example, without the directive, I get a compile error "Variable identifier expected". Interestingly, WITH the directive I also get the same compile error. See the screenshot.

If I replace += with normal fp syntax, everything compiles just fine. My suggestion: stick to native fp syntax. Even though it may look more verbose, the resulting code is the same.

Example:
Code: Pascal  [Select]
  1. unit upcstyle;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$COPERATORS ON}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Label1: TLabel;
  17.     procedure FormCreate(Sender: TObject);
  18.   private
  19.     { private declarations }
  20.   public
  21.     { public declarations }
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.FormCreate(Sender: TObject);
  34. var
  35.   EmptyStr: boolean;
  36.   HtmlClass: string;
  37. begin
  38.   EmptyStr := (HtmlClass = '');
  39.   if EmptyStr then
  40.     Label1.Caption += 'empty' //doesn't work
  41.     //Label1.Caption := Label1.Caption + 'empty' //works
  42.   else
  43.     Label1.Caption := 'not empty';
  44. end;
  45.  
  46. end.
  47.  

Steps to reproduce: Start a new project. Add a label to the form. Replace the code in unit1 with the example code.

EDIT: I just learned that {$mode objfpc} already gives support to C style operators. It explains why the compiler keeps complaining. In the example above {$COPERATORS ON} doesn't make any difference.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: engkin on October 18, 2017, 05:15:17 am
Before I get ahead of myself and post this as a bug, I thought I would ask here first.
Consider line 8 in the code fragment below: The code uses +=, whereas the commented assignment on line nine  uses :=
When I run the code as is (with +=) and the boolean variable, EmptyStr on line seven is true, the debugger exits the method as if the code on lines eight and ten does not exist. But when I comment that line and uncomment line nine, then the code functions properly.

Am I simply misusing +=? I mean CurrentString is a variable passed to method where this code is implemented and MIF_EmtyCharStyleMarker is a constant declared in another unit.
 
Code: Pascal  [Select]
  1.           Case WordHTMLTag of
  2.             wht_Italics : CurrentString += MIF_ItalicMarker;
  3.             wht_Bold    : CurrentString += MIF_BoldMarker  ;
  4.             wht_span    : If IsOpeningTag
  5.                           then begin
  6.                             EmptyStr := HtmlClass = '';
  7.                             If EmptyStr then
  8.                                CurrentString += MIF_EmptyCharStyleMarker
  9.                            // CurrentString := CurrentString + MIF_EmptyCharStyleMarker
  10.                             else MIF_AddStartCharaTag(HTMLClass)
  11.                           end
  12.                           else If MIF_HasIllegalMarker(CurrentString)
  13.                                then CurrentString += MIF_EmptyCharStyleMarker
  14.                                else MIF_AddEndCharaTag;
  15.             else Assert(False, 'we should not bere here!');
  16.            end;
  17.  

Your usage is correct.
The generated code is also correct.
There is a bug in the debug information, confirmed using -al in the compiler options

When += is used here is the generated code:
Quote
.Ll28:
# [46] If EmptyStr then
   cmpb   $0,-20(%ebp)
   je   .Lj58
.Ll29:
# [49] else
   pushl   $0
   movl   8(%ebp),%eax
   movl   (%eax),%edx
   movl   8(%ebp),%eax
   movl   TC_$P$PROJECT1_$$_MIF_EMPTYCHARSTYLEMARKER,%ecx
   call   fpc_ansistr_concat
   jmp   .Lj32

While with CurrentString := CurrentString + MIF_EmptyCharStyleMarker
Quote
.Ll28:
# [46] If EmptyStr then
   cmpb   $0,-20(%ebp)
   je   .Lj58
.Ll29:
# [48] CurrentString := CurrentString + MIF_EmptyCharStyleMarker
   pushl   $0
   movl   8(%ebp),%eax
   movl   (%eax),%edx
   movl   8(%ebp),%eax
   movl   TC_$P$PROJECT1_$$_MIF_EMPTYCHARSTYLEMARKER,%ecx
   call   fpc_ansistr_concat
   jmp   .Lj32

Notice that the assembly is identical. Just the debug information is wrong.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 05:23:33 am
Does that mean that the directive {$COPERATORS ON} no longer makes a difference? My example suggests it is not just the debugger.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: EganSolo on October 18, 2017, 06:53:41 am
Thank you, everyone, for your thoughtful responses. This was extremely helpful and enlightening. I did not think to use the -al option, now I know better.

So, should I report this as a bug?
 
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Thaddy on October 18, 2017, 09:22:07 am
Does that mean that the directive {$COPERATORS ON} no longer makes a difference? My example suggests it is not just the debugger.
Depends on mode: in objfpc mode it is on by default. In mode delphi it is off by default. So {$COPERATORS ON} is basically just required if you want to use it in other modes than {$mode objfpc}
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 09:45:28 am
Does that mean that the directive {$COPERATORS ON} no longer makes a difference? My example suggests it is not just the debugger.
Depends on mode: in objfpc mode it is on by default. In mode delphi it is off by default. So {$COPERATORS ON} is basically just required if you want to use it in other modes than {$mode objfpc}
Then my example above should be considered a bug. I never use c-style operators. This is the first issue I run into taking the TS problem.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Thaddy on October 18, 2017, 09:47:56 am
I don't see the bug?
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 09:49:43 am
I don't see the bug?
See my first comment with screenshot. It doesn't compile here.

Clearly the compiler expects something else from line 40 to 41. It doesn't seem to support the += construction followed by the ELSE statement.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Thaddy on October 18, 2017, 10:23:52 am
The C style operators need to be fully evaluated first. It is C style, and certainly not complete (e.g. use =+ etc are not implemented)
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 10:25:49 am
The C style operators need to be fully evaluated first. It is C style, and certainly not complete (e.g. use =+ etc are not implemented)
Which is why I suggested to stick to FP syntax.  ;)
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Leledumbo on October 18, 2017, 11:02:57 am
In this case, the two should be identical. Can you make a super simple example that still reproduce this issue so that we can confirm?
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 11:28:46 am
In this case, the two should be identical. Can you make a super simple example that still reproduce this issue so that we can confirm?

Even if I take out the ELSE condition, the compiler still complains:
Code: Pascal  [Select]
  1. if EmptyStr then
  2.   Label1.Caption += 'empty'; //complaint

The compiler also complains without IF condition:
Code: Pascal  [Select]
  1. Label1.Caption += ''; //complaint

However, the compiler does not complain when using simple variables:
Code: Pascal  [Select]
  1. var a: string;
  2. a += ''; //no complaint
  3. Label1.Caption += ''; //complaint

It looks like it has to do with the combination of object referencing.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Blaazen on October 18, 2017, 02:16:56 pm
@ It looks like it has to do with the combination of object referencing.

No. It has to do with properties. Operator += needs variable. Setters and getters have no address.
It seems that CurrentString from the original post is a property.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 04:15:58 pm
@ It looks like it has to do with the combination of object referencing.

No. It has to do with properties. Operator += needs variable. Setters and getters have no address.
It seems that CurrentString from the original post is a property.
Object properties are referenced / dereferenced during execution, if I'm not mistaken. So the problem is referencing as opposed to variable address.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: engkin on October 18, 2017, 07:54:24 pm
In this case, the two should be identical. Can you make a super simple example that still reproduce this issue so that we can confirm?

Consider the following program:
Code: Pascal  [Select]
  1. program minimal;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses {$IFDEF UNIX} {$IFDEF UseCThreads}
  6.   cthreads, {$ENDIF} {$ENDIF}
  7.   Classes { you can add units after this };
  8.  
  9. var
  10.   boolVar: boolean = True;
  11.   SomeVar: integer = 0;
  12. begin
  13.   if boolVar then
  14.     SomeVar += 1
  15.   else
  16.     SomeVar := SomeVar - 1;
  17. end.

When you debug this program it should start at
Code: Pascal  [Select]
  1.   if boolVar then
then:
Code: Pascal  [Select]
  1.     SomeVar += 1
and finally:
Code: Pascal  [Select]
  1. end.
That is the expected behavior. BUT the current behavior is different at the second step. Instead of showing 
Code: Pascal  [Select]
  1.     SomeVar += 1
it shows:
Code: Pascal  [Select]
  1.   else

If you replace += with the full syntax  SomeVar := SomeVar + 1 you will see the correct expected behavior.



Here is GDB output when using C operator:
Quote
13        if boolVar then
(gdb) n
15        else
(gdb)
17      end.
(gdb)


Here is GDB output *without* C operator:
Quote
13        if boolVar then
(gdb) n
14          SomeVar := SomeVar + 1
(gdb)
17      end.
(gdb)
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 08:15:11 pm
@engkin, there seem to be two issues here (at least).

1. The debugger does not fully support C-style operators.

2. C-style operators can only be used with simple variables. As demonstrated in an earlier comment, C-style operators won't work with object properties.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: engkin on October 18, 2017, 08:38:40 pm
@engkin, there seem to be two issues here (at least).

1. The debugger does not fully support C-style operators.

The debugger knows what FPC saved in the debug information. IAW, FPC generates wrong debug information for C operators. Specifically, wrong line number.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: Munair on October 18, 2017, 09:56:54 pm
@engkin, there seem to be two issues here (at least).

1. The debugger does not fully support C-style operators.

The debugger knows what FPC saved in the debug information. IAW, FPC generates wrong debug information for C operators. Specifically, wrong line number.
Yes, thanks for correcting me there. Suffice it to say, better not use C-style operators.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: engkin on October 19, 2017, 04:36:06 am
@engkin, there seem to be two issues here (at least).

1. The debugger does not fully support C-style operators.

The debugger knows what FPC saved in the debug information. IAW, FPC generates wrong debug information for C operators. Specifically, wrong line number.
Yes, thanks for correcting me there. Suffice it to say, better not use C-style operators.

What if this bug is not limited to C operators?

I believe this bug should be reported.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: EganSolo on October 19, 2017, 05:42:27 am
Don't use C-style operators. Got it.

So... should I report this or will someone else do it? I'm fine either way. I just want to know :)
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: engkin on October 19, 2017, 05:57:19 am
Yes, please do. Otherwise it will be forgotten.
Title: Re: Difference between += and := -- Is this a bug in FPC?
Post by: schuler on October 25, 2017, 12:39:01 am
Quick note: Caption is a property (not a variable).