Recent

Author Topic: inconsistent FPC behavior in corner case  (Read 1961 times)

440bx

  • Hero Member
  • *****
  • Posts: 3944
inconsistent FPC behavior in corner case
« on: February 12, 2020, 02:50:29 am »
Hello,

Consider the following short program
Code: Pascal  [Select][+][-]
  1. {   1 }
  2. {   2 } program TestNameResolution;
  3. {   3 }
  4. {   4 } const
  5. {   5 }   b = 1;                       // define b
  6. {   6 }
  7. {   7 } type
  8. {   8 }   T = array[1..10] of integer; // define T
  9. {   9 }
  10. {  10 }   procedure X;
  11. {  11 }   const
  12. {  12 }     b = b;                     // resolves using first const definition
  13. {  13 }
  14. {  14 }   type
  15. {  15 }     T = array[1..10] of T;     // doesn't resolve using the first type
  16. {  16 }                                // definition (it should, just as for b)
  17. {  17 }   begin
  18. {  18 }   end;
  19. {  19 }
  20. {  20 } begin
  21. {  21 } end.
  22.  
FPC accepts, as it should, the constant definition "b = b" because b has been defined in a previous block but, it doesn't behave the same way when it resolves type definitions.  In the case of type T, it doesn't use the existing definition of T, instead it declares an "illegal expression".

Just for the record, Delphi refused to compile either statement (at least it's consistent.)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14203
  • Probably until I exterminate Putin.
Re: inconsistent FPC behavior in corner case
« Reply #1 on: February 12, 2020, 08:32:38 am »
It is not a corner case, but borderline programming ;)
If such a pattern proves necessary put the global declarations in a separate unit, so you can qualify them.
Code: Pascal  [Select][+][-]
  1. {   2 } program TestNameResolution;
  2. {   3 } uses globs;
  3. {   9 }
  4. {  10 }   procedure X;
  5. {  11 }   const
  6. {  12 }     b = globs.b;                     // resolves
  7. {  13 }
  8. {  14 }   type
  9. {  15 }     T = array[1..10] of globs.T;     // also resolves
  10. {  17 }   begin
  11. {  18 }   end;
  12. {  19 }
  13. {  20 } begin
  14. {  21 } end.
Code: Pascal  [Select][+][-]
  1. unit globs;
  2. interface
  3. {   4 } const
  4. {   5 }   b = 1;                       // define b
  5. {   6 }
  6. {   7 } type
  7. {   8 }   T = array[1..10] of integer; // define T
  8. implementation
  9. end.
If b=b really works you may have a point, though. I would ask on the devel mailing list before posting a bug, though. There may be an explanation we overlooked.
 
« Last Edit: February 12, 2020, 08:43:17 am by Thaddy »
Specialize a type, not a var.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: inconsistent FPC behavior in corner case
« Reply #2 on: February 12, 2020, 09:29:33 am »
If b=b really works you may have a point, though. I would ask on the devel mailing list before posting a bug, though. There may be an explanation we overlooked.

Delphi 7 allows that too.

Bart

Thaddy

  • Hero Member
  • *****
  • Posts: 14203
  • Probably until I exterminate Putin.
Re: inconsistent FPC behavior in corner case
« Reply #3 on: February 12, 2020, 10:37:20 am »
[Delphi 7 allows that too.

Bart
Both? The issue is about the array and that is refused.
Specialize a type, not a var.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: inconsistent FPC behavior in corner case
« Reply #4 on: February 12, 2020, 12:54:10 pm »
It is not a corner case, but borderline programming ;)
That's putting it kindly... a very thin border. <chuckle>

If b=b really works you may have a point, though. I would ask on the devel mailing list before posting a bug, though. There may be an explanation we overlooked.
b = b does work and, it should work (note: I'm not saying it's good programming only that it should work), for the same reason the declaration of the T array of T should also work.  Both cases reflect the timing a type definition is added to the parser's tables.


Delphi 7 allows that too.
Interesting, Delphi 2 refused both statements. 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14203
  • Probably until I exterminate Putin.
Re: inconsistent FPC behavior in corner case
« Reply #5 on: February 12, 2020, 01:08:42 pm »
Comparing to D2 is a bit gross, but if b = b works, so the array should work. I will fire up D7 to check if Bart's statement is really true for both. My guess is: not!
BTW I also use D2 if size matters, but 32 bit windows is not something I regularly target.
Specialize a type, not a var.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: inconsistent FPC behavior in corner case
« Reply #6 on: February 12, 2020, 02:46:53 pm »
Borland Delphi Version 15.0 (That's D7 for you)
Copyright (c) 1983,2002 Borland Software Corporation
test.pas(11) Error: Type 'T' is not yet completely defined
test.pas(16)

Code: Pascal  [Select][+][-]
  1. {10}type
  2. {11}  T = array[0..1] of T;

Bart

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: inconsistent FPC behavior in corner case
« Reply #7 on: February 12, 2020, 05:21:40 pm »
Both cases reflect the timing a type definition is added to the parser's tables.
For types, the name is included in the table immediately to allow such definitions:
Code: Pascal  [Select][+][-]
  1. type
  2.   TSome = class
  3.     X: TSome;
  4.   end;
As a result in
Code: Pascal  [Select][+][-]
  1. T = array[0..1] of T;
Type 'T' is not yet completely defined.

Thaddy

  • Hero Member
  • *****
  • Posts: 14203
  • Probably until I exterminate Putin.
Re: inconsistent FPC behavior in corner case
« Reply #8 on: February 12, 2020, 05:37:52 pm »
Borland Delphi Version 15.0 (That's D7 for you)
Copyright (c) 1983,2002 Borland Software Corporation
test.pas(11) Error: Type 'T' is not yet completely defined
test.pas(16)

Code: Pascal  [Select][+][-]
  1. {10}type
  2. {11}  T = array[0..1] of T;

Bart
Therefor your observation is correct. Just tested D7 too. So Delph 7 is also inconsistent.
I agree with ASerge that a circular reference should not be allowed so basically the current behavior is explained sufficiently.
This seems not a bug to me.
« Last Edit: February 12, 2020, 05:43:07 pm by Thaddy »
Specialize a type, not a var.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: inconsistent FPC behavior in corner case
« Reply #9 on: February 12, 2020, 05:49:29 pm »
As a result in
Code: Pascal  [Select][+][-]
  1. T = array[0..1] of T;
Type 'T' is not yet completely defined.
But T is completely defined, just in another block, just like the constant "b". 

The problem is that it added the current T type definition into the parser's tables and, because of that when searching for the definition of T (as the type of array element), it finds the incomplete definition instead of the previously defined T.  IOW, it added the current type definition too early, that caused the masking of the previous full definition of T.  In the case of the constant "b", the fact that it finds the previous definition indicates that the current definition was _not_ added to the parser's table until the definition was complete.  That prevented the previous definition of "b" from being masked away by the new one.

All that said, re-using names in the same definition (such as "b" and "T") is a very poor practice so, maybe it's better that FPC does it that way even though, strictly speaking, it is "questionable".

I see your point about the class definitions, you're right, for classes it does need to add the type early in the parser's table.  That's probably why it initially marks it "incomplete" and it accepts a reference to the class because unlike in a "normal" type definition, a reference to a class is just a pointer and that's all it really needs to know at that point.

This seems not a bug to me.
Strictly speaking, it is incorrect.  Pascal's scope rules allow the definition of T as I posted it.  OTOH, losing the ability of creating such questionable definitions is more a blessing than anything else.  That said, if it allows it for constants then it should allow it for types too.  Either allow it or don't allow it but, not "allow sometimes" and "don't allow other times".


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14203
  • Probably until I exterminate Putin.
Re: inconsistent FPC behavior in corner case
« Reply #10 on: February 12, 2020, 06:30:54 pm »
I agree. But  there are compatibility reasons to take in account. Is this somewhere marked as a bug in Delphi?
Specialize a type, not a var.

FPK

  • Moderator
  • Full Member
  • *****
  • Posts: 118
Re: inconsistent FPC behavior in corner case
« Reply #11 on: February 12, 2020, 09:49:24 pm »
Type blocks needs some special handling in this case as stuff like

Code: [Select]
type
  tc = class
    owner : tc;
  end;

must be possible.

Thaddy

  • Hero Member
  • *****
  • Posts: 14203
  • Probably until I exterminate Putin.
Re: inconsistent FPC behavior in corner case
« Reply #12 on: February 12, 2020, 09:56:36 pm »
I will trust the benevolent dictator for life. 8-) ;D
Specialize a type, not a var.

 

TinyPortal © 2005-2018