Bookstore

Recent

Author Topic: Possible FPC bug in corner case  (Read 532 times)

440bx

  • Hero Member
  • *****
  • Posts: 1568
Possible FPC bug in corner case
« on: February 11, 2020, 09:45:26 am »
Hello,

FPC won't compile the program below even though it is valid Pascal.
Code: Pascal  [Select]
  1. program TestNames;
  2.  
  3. procedure B;
  4. var
  5.   B : integer;
  6. begin
  7.   if B = 1 then  // can access the variable but...
  8.   begin
  9.     dec(B);
  10.     B;           // won't allow recursive call with or without parentheses
  11.   end;
  12. end;
  13.  
  14. begin
  15. end.  
  16.  
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8072
Re: Possible FPC bug in corner case
« Reply #1 on: February 11, 2020, 10:00:35 am »
I think this is normal? Local variable B overrides procedure B in symbol table, so you can't call it.

440bx

  • Hero Member
  • *****
  • Posts: 1568
Re: Possible FPC bug in corner case
« Reply #2 on: February 11, 2020, 10:23:12 am »
I think this is normal? Local variable B overrides procedure B in symbol table, so you can't call it.
Theoretically, it shouldn't do that.  The procedure name "B" is one level above the procedure's parameters (when there are any) and its local variables.  The compiler is supposed to be able to figure out if "B" is a reference to the variable or procedure by looking at the token that follows "B" which will be different.  A variable reference will be followed by either an assignment ":=", a field selector (.) or an index ([) selector whereas a procedure/function will be followed by either an open parenthesis or a semicolon.  (I'm not sure if there are any other possibilities with FPC but, those would be the one's for standard Pascal.)

All that said, Delphi didn't compile it either but, it should compile (and work correctly, of course ;) )
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8072
Re: Possible FPC bug in corner case
« Reply #3 on: February 11, 2020, 10:49:25 am »
Nope, it can't. Pascal looks through a scope stack of identifiers and returns on first match.

There are two exceptions afaik (though Pascaldragon will probably correct me):
  • Various forms of overloading of procedures,methods
  •   x : x; in records where the first name is an fieldname declaration , and the second a type, for winapi's benefit

440bx

  • Hero Member
  • *****
  • Posts: 1568
Re: Possible FPC bug in corner case
« Reply #4 on: February 11, 2020, 11:45:07 am »
Pascal looks through a scope stack of identifiers and returns on first match.
That is correct.  When searching for a variable, the compiler starts at the current block and goes up from there towards the standard block but, in this case, the compiler _knows_ that what it's dealing with is a _procedure call_ not a variable access, therefore looking for a variable isn't the right thing to do.  It's looking for the wrong thing, it should be looking for a procedure, therefore start the search one block above the current one which is where the current procedure is defined.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8072
Re: Possible FPC bug in corner case
« Reply #5 on: February 11, 2020, 12:09:31 pm »
Pascal looks through a scope stack of identifiers and returns on first match.
That is correct.  When searching for a variable, the compiler starts at the current block and goes up from there towards the standard block but, in this case, the compiler _knows_ that what it's dealing with is a _procedure call_ not a variable access, therefore looking for a variable isn't the right thing to do.  It's looking for the wrong thing, it should be looking for a procedure, therefore start the search one block above the current one which is where the current procedure is defined.

Those scopes are for *identifiers* in general.

Zoran

  • Hero Member
  • *****
  • Posts: 1504
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Possible FPC bug in corner case
« Reply #6 on: February 11, 2020, 01:16:06 pm »
Those scopes are for *identifiers* in general.

However, when resolving function return value vs. recursive call, the compiler decides by parentheses:
Code: Pascal  [Select]
  1. program Project1;
  2.  
  3. var
  4.   N: Integer = 4;
  5.  
  6. function TestFun: Integer;
  7. begin
  8.   if N > 0 then begin
  9.     Dec(N);
  10.  
  11. { In the following line, the compiler sees TestFun without parentheses
  12.   as the function result, but with parentheses it is a recursive call: }
  13.     TestFun := TestFun();
  14.  
  15.   end else begin
  16.     TestFun := N;
  17.     N := 4;
  18.   end;
  19. end;
  20.  
  21. begin
  22.   WriteLn('The result is ', TestFun);
  23.   ReadLn;
  24. end

But the posted procedure works only if you add program/unit prefix in front:
Code: Pascal  [Select]
  1. procedure B;
  2. var
  3.   B : integer;
  4. begin
  5.   if B = 1 then  // can access the variable but...
  6.   begin
  7.     dec(B);
  8.     TestNames.B();  // with or without parentheses
  9.   end;
  10. end;
« Last Edit: February 11, 2020, 01:18:52 pm by Zoran »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8072
Re: Possible FPC bug in corner case
« Reply #7 on: February 11, 2020, 02:10:21 pm »
Those scopes are for *identifiers* in general.

However, when resolving function return value vs. recursive call, the compiler decides by parentheses:

Yes. But that is a form of overloading more or less. One symbol, with two possible meanings.

Quote
But the posted procedure works only if you add program/unit prefix in front:

If not a nested procedure.  Maybe that works as  unitname.outerproc.innerproc though.
« Last Edit: February 11, 2020, 02:26:57 pm by marcov »

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2507
Re: Possible FPC bug in corner case
« Reply #8 on: February 11, 2020, 02:16:45 pm »
Its consistent for all kinds of variables. If you modify your example a bit:
Code: Pascal  [Select]
  1.     program TestNames;
  2.      
  3.     procedure B;
  4.     var
  5.       B : procedure;
  6.     begin
  7.       if assigned(B) then  // can access the variable but...
  8.       begin
  9.         B := @someProc;
  10.         B;           // what would be called here ?
  11.       end;
  12.     end;
  13.      
  14.     begin
  15.     end.  
  16.  
     

So if the compiler would accept your first example, it cannot handle this example the same manner. This means that the behaviour is dependent on the type of variable. This is IMO unwanted.
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

440bx

  • Hero Member
  • *****
  • Posts: 1568
Re: Possible FPC bug in corner case
« Reply #9 on: February 11, 2020, 03:08:59 pm »
So if the compiler would accept your first example, it cannot handle this example the same manner. This means that the behaviour is dependent on the type of variable. This is IMO unwanted.
Your point is definitely valid.  IMO, all the undesirable problems come from allowing a variable (or even a parameter) to be named the same as the procedure.   For the record, I consider that atrocious programming but, since the compiler allows it, I feel it should deal with it.  That said, I believe the reasonable solution is to not allow a variable and/or parameter to be named the same as the procedure just as the compiler does for a function.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2507
Re: Possible FPC bug in corner case
« Reply #10 on: February 11, 2020, 05:25:52 pm »
I recall something about a warning, but that might only be for properties
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker