Recent

Author Topic: Unexpected FPC v3.0.4 Behavior  (Read 6948 times)

440bx

  • Hero Member
  • *****
  • Posts: 6022
Unexpected FPC v3.0.4 Behavior
« on: June 27, 2020, 03:08:14 am »
Hello,

First, I don't know if the new version of FPC behaves the same way, I am still using v3.0.4.

Consider the sample program below:
Code: Pascal  [Select][+][-]
  1. { without any of the defines below, FPC v3.0.4 compiles this sample program   }
  2. { Delphi v2.0 does NOT.                                                       }
  3.  
  4. { with any of the defines active, FPC complains about one thing or another    }
  5. { and the compile fails.                                                      }
  6.  
  7. //{$DEFINE CALL_A}
  8. //{$DEFINE CALL_B}
  9. //{$DEFINE CALL_C}
  10.  
  11. program TestProcedureName;
  12.  
  13.   type
  14.     ProcedureName = array[1..2] of integer;
  15.  
  16.   procedure ProcedureA;
  17.  
  18.     procedure ProcedureName(ParameterA : ProcedureName);
  19.     begin
  20.       { if no attempt is made to use ParameterA then the program compiles     }
  21.  
  22.       { neither of the statements below are accepted    }
  23.  
  24.  
  25.       { illegal expression                                                    }
  26.  
  27.       {$IFDEF CALL_A} ParameterA;                {$ENDIF}
  28.  
  29.  
  30.       { illegal expression;   Syntax error, ";" expected but "(" found        }
  31.  
  32.       {$IFDEF CALL_B} ParameterA(ParameterA);    {$ENDIF}
  33.  
  34.  
  35.       { illegal expression;   Syntax error, ";" expected but "(" found        }
  36.  
  37.       {$IFDEF CALL_C} ParameterA(ProcedureName); {$ENDIF}
  38.     end;
  39.  
  40.   begin
  41.   end;
  42.  
  43.  
  44. begin
  45. end.
  46.  
When _none_ of the defines are active the program compiles.  Once any of the defines are active the compiler will complain about one thing or another.

With none of the defines active, unlike FPC, Delphi v2.0 does _not_ compile the program.

Aside from the difference in behavior between Delphi and FPC, I do not see how FPC expects ParameterA to be used.  I suppose that, if it considers the sample program correct, there must be a way to use ParameterA but, it doesn't seem to like any of the expected constructions (and a few possibly unexpected ones too ;) (unexpected constructions not included in the sample.))
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Kays

  • Hero Member
  • *****
  • Posts: 632
  • Whasup!?
    • KaiBurghardt.de
Re: Unexpected FPC v3.0.4 Behavior
« Reply #1 on: June 27, 2020, 06:20:58 am »
What are you trying to achieve? I can’t figure out what your program is supposed to do.
  • ParameterA is a (is of type) array[1..2] of integer. You can’t just put ParameterA in a routine’s definition. You have to insert statements between begin and end. Writing ParameterA is a factor of an expression.
  • ParameterA is neither a function, nor a type. You can’t put parentheses after it.
  • Same as B.
Maybe, did you want to use procedural variables such as TProcedure?
Yours Sincerely
Kai Burghardt

440bx

  • Hero Member
  • *****
  • Posts: 6022
Re: Unexpected FPC v3.0.4 Behavior
« Reply #2 on: June 27, 2020, 06:32:37 am »
What are you trying to achieve? I can’t figure out what your program is supposed to do.
It's just a program to test FPC's scope resolution algorithms and the timing of the addition of identifiers in its parse tables.

As far as the rest of your post, your questions are completely valid because, I don't see how it makes any sense for the compiler to accept and, successfully compile that code.  IOW, that code should _not_ compile (even when none of the defines are enabled).  That's part of what I am testing.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Unexpected FPC v3.0.4 Behavior
« Reply #3 on: June 27, 2020, 07:25:10 am »
Just shooting in the dark here, but maybe it's finding an empty procedure and optimizing it all away? Though how it can even arrive at that without getting lost among all those ProcedureName baffles me no end ... :-\
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

440bx

  • Hero Member
  • *****
  • Posts: 6022
Re: Unexpected FPC v3.0.4 Behavior
« Reply #4 on: June 27, 2020, 08:26:40 am »
Though how it can even arrive at that without getting lost among all those ProcedureName baffles me no end ... :-\
All the ProcedureName (s) are ok up until the one used as the type of ParameterA, that one is _not_ ok.  The compiler should _not_ have accepted that instance of ProcedureName because in that location, it identifies a procedure not a type.

As far as the usage of "ProcedureName" it could be worse!... For instance, it could be like this:
Code: Pascal  [Select][+][-]
  1. program TestProcedureNameB;
  2.  
  3.   type
  4.     ProcedureName = array[1..2] of integer;
  5.  
  6.   procedure ProcedureA;
  7.  
  8.     procedure ProcedureName(ProcedureName : ProcedureName);
  9.     begin
  10.     end;
  11.  
  12.   begin
  13.   end;
  14.  
  15.  
  16. begin
  17. end.
  18.  
That's not valid Pascal but, a very simple change makes it valid Pascal, as shown below:
Code: Pascal  [Select][+][-]
  1. program TestProcedureNameB;
  2.  
  3.   type
  4.     ProcedureName = array[1..2] of integer;
  5.  
  6.   procedure ProcedureA;
  7.  
  8.     procedure ProcedureName(ProcedureName : integer);  { valid Pascal in spite of all the "ProcedureName" (s) }
  9.     begin
  10.     end;
  11.  
  12.   begin
  13.   end;
  14.  
  15.  
  16. begin
  17. end.
  18.  

ETA:
I forgot to mention, the "worse" (top in this post) example of reusing "ParameterName" also compiles with FPC.

« Last Edit: June 27, 2020, 08:42:10 am by 440bx »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Kays

  • Hero Member
  • *****
  • Posts: 632
  • Whasup!?
    • KaiBurghardt.de
Re: Unexpected FPC v3.0.4 Behavior
« Reply #5 on: June 27, 2020, 08:56:48 am »
[…] All the ProcedureName (s) are ok up until the one used as the type of ParameterA, that one is _not_ ok.  The compiler should _not_ have accepted that instance of ProcedureName because in that location, it identifies a procedure not a type.[…]
OK, now I see the problem.

There’s one table with all identifiers identifying types.

And there’s one table with all identifiers identifying routines.

While parsing the formal parameters of the procedure ProcedureName after the colon the compiler expects a type identifier, thus (only) looks up the type identifier table. At that point, however, the routine ProcedureName is neither declared (= forward declaration) nor defined (= parsing of the beginend frame).

Are you saying, all identifiers have to be unique and can’t be both a label and a type identifier at the same time?
Yours Sincerely
Kai Burghardt

MarkMLl

  • Hero Member
  • *****
  • Posts: 8525
Re: Unexpected FPC v3.0.4 Behavior
« Reply #6 on: June 27, 2020, 09:00:50 am »
I know that this is a very minor niggle, but on the principle that when a programmer has a hard time finding a bug it's usually because he's looking in the wrong place I'd suggest replacing your  //{$DEFINE CALL_A}  and similar with  { DEFINE CALL_A}  etc., just in case different compilers or different FPC modes are getting confused by the continued presence of  <comment marker><literal dollar>

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 6022
Re: Unexpected FPC v3.0.4 Behavior
« Reply #7 on: June 27, 2020, 09:25:40 am »
There’s one table with all identifiers identifying types.

And there’s one table with all identifiers identifying routines.
As far as that goes, the compiler writer could choose to do it that way but, the most common way (because it's the most convenient) is to have only _one_ table which, among other things has the identifier name (usually an id) and it type (also an id) then, there is the scope table, which is a list of references into that previous table which tracks which identifiers (and their types) are valid/known in that scope.

When the compiler encounters "procedure ProcedureName", the "ProcedureName" is added to the scope that was started by "ProcedureA" and creates a _new_ scope for "ProcedureName" because procedure parameters are one scope below the procedure name, that's what allows a parameter name to have the same name as the procedure yet, be considered a different identifier and also makes the procedure's local variables be in the same scope as the procedure parameters (as they should be.)

In the test program I posted, when the compiler looks for what "ProcedureName" means, it should be finding the definition from "Procedure ProcedureName" which identifies "ProcedureName" as a procedure, not a data type.  For this reason it should not accept "ProcedureName" as a data type identifier since it isn't one.

While parsing the formal parameters of the procedure ProcedureName after the colon the compiler expects a type identifier, thus (only) looks up the type identifier table. At that point, however, the routine ProcedureName is neither declared (= forward declaration) nor defined (= parsing of the beginend frame).
It is declared and, it finds it.  Proof of that is the message from the compiler stating that it expected a semicolon ";" when an attempt is made to use ParameterA in a statement, it knows ParameterA is a procedure, specifically a "ProcedureName".

Are you saying, all identifiers have to be unique and can’t be both a label and a type identifier at the same time?
No.  In this particular case, I'm saying that "ParameterName" does not identify a data type therefore it is invalid to use it as if it were one.



I know that this is a very minor niggle, but on the principle that when a programmer has a hard time finding a bug it's usually because he's looking in the wrong place I'd suggest replacing your  //{$DEFINE CALL_A}  and similar with  { DEFINE CALL_A}  etc., just in case different compilers or different FPC modes are getting confused by the continued presence of  <comment marker><literal dollar>
Your suggestion is welcome.  I just want to mention that this is just a simple little test.  If the compiler gets confused with those defines, that would be another bug.  <chuckle>
« Last Edit: June 27, 2020, 09:27:53 am by 440bx »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Unexpected FPC v3.0.4 Behavior
« Reply #8 on: June 27, 2020, 10:36:42 am »
Aside from the difference in behavior between Delphi and FPC, I do not see how FPC expects ParameterA to be used.
That's an easy one  :D just as you would expect it to.

Code: Pascal  [Select][+][-]
  1.       {$IFDEF CALL_A} ParameterA[1] := 12;                {$ENDIF}
  2.  

Not that the code actually makes any sense but i believe that was besides the point ?
Today is tomorrow's yesterday.

ASerge

  • Hero Member
  • *****
  • Posts: 2475
Re: Unexpected FPC v3.0.4 Behavior
« Reply #9 on: June 27, 2020, 10:42:08 am »
I'd suggest replacing your  //{$DEFINE CALL_A}  and similar with  { DEFINE CALL_A}  etc., just in case different compilers or different FPC modes are getting confused by the continued presence of  <comment marker><literal dollar>
In this case, after a double slash, the string is treated as a comment only.

For 440bx: it was easier to provide the mentioned small example, so as not to confuse the people. This code is compiled in FPC, but not in Delphi:
Code: Pascal  [Select][+][-]
  1. type
  2.   ProcedureName = array[1..2] of Integer;
  3.  
  4. procedure ProcedureA;
  5.   procedure ProcedureName(ProcedureName: ProcedureName);
  6.   begin
  7.   end;
  8. begin
  9. end;
  10.  
  11. begin
  12. end.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8525
Re: Unexpected FPC v3.0.4 Behavior
« Reply #10 on: June 27, 2020, 10:49:34 am »
I'd suggest replacing your  //{$DEFINE CALL_A}  and similar with  { DEFINE CALL_A}  etc., just in case different compilers or different FPC modes are getting confused by the continued presence of  <comment marker><literal dollar>
In this case, after a double slash, the string is treated as a comment only.

I know that's what /should/ happen... :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Unexpected FPC v3.0.4 Behavior
« Reply #11 on: June 27, 2020, 10:57:39 am »
Code: Pascal  [Select][+][-]
  1. ...
  2.  
Now, that snippet seems to be more problematic.

Can't seem to differentiate whatsoever inside the nested procedure itself by what you want to use, the procedure or the parameter. The type can still be addressed by using the unit scope.

Would be nice to be able to use self in such cases ?
Today is tomorrow's yesterday.

440bx

  • Hero Member
  • *****
  • Posts: 6022
Re: Unexpected FPC v3.0.4 Behavior
« Reply #12 on: June 27, 2020, 11:05:30 am »
That's an easy one  :D just as you would expect it to.

Code: Pascal  [Select][+][-]
  1.       {$IFDEF CALL_A} ParameterA[1] := 12;                {$ENDIF}
  2.  
I could have sworn I had tried that but, obviously I didn't since, you're right, FPC compiles that and, it most definitely should not since it should not see ProcedureName as an array type.

Not that the code actually makes any sense but i believe that was besides the point ?
You're right.  The code doesn't make any sense which is why it shouldn't compile.



For 440bx: it was easier to provide the mentioned small example, so as not to confuse the people. This code is compiled in FPC, but not in Delphi:
Point taken but, it wasn't my intention to confuse anyone, just to show what I had tried and provide an easy way for others to try those things and see the results for themselves.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Unexpected FPC v3.0.4 Behavior
« Reply #13 on: June 27, 2020, 11:10:15 am »
... it most definitely should not since it should not see ProcedureName as an array type.
Isn't that a matter of interpretation ?

I looked at it from the point: last defined, first served (or overruled if you so like since i can't seem to address the procedure itself whatsoever). Then it seems pretty logical ?

edit: e.g. the use of the parenthesis should have helped the compiler but it didn't.
« Last Edit: June 27, 2020, 11:14:31 am by TRon »
Today is tomorrow's yesterday.

440bx

  • Hero Member
  • *****
  • Posts: 6022
Re: Unexpected FPC v3.0.4 Behavior
« Reply #14 on: June 27, 2020, 11:28:38 am »
... it most definitely should not since it should not see ProcedureName as an array type.
Isn't that a matter of interpretation ?

I looked at it from the point: last defined, first served (or overruled if you so like since i can't seem to address the procedure itself whatsoever). Then it seems pretty logical ?
No, because when the compiler searches for the definition of ParameterName in the scopes stack, it's supposed to find the definition of ParameterName as a procedure first since the definition as an array is further above it and the scope for ProcedureName _must_ already be defined when it starts parsing the procedure parameters because they must belong to the ProcedureName procedure scope.

edit: e.g. the use of the parenthesis should have helped the compiler but it didn't.
The compiler will not use syntactic elements to determine the scope of an identifier (though it can use them to eliminate ambiguities).  [addition] For scope resolution, [/addition] it will only use scope identifiers such as the program name, unit name, etc.
« Last Edit: June 27, 2020, 11:30:10 am by 440bx »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018