Recent

Author Topic: [solved] Confusing scope(s) for typed constant  (Read 1241 times)

TRon

  • Hero Member
  • *****
  • Posts: 1849
[solved] Confusing scope(s) for typed constant
« on: September 25, 2023, 11:05:47 am »
Code speaks louder than words:
Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. // documentation:
  6. // - https://www.freepascal.org/docs-html/ref/refse23.html
  7. // - https://www.freepascal.org/docs-html/current/ref/refse23.html#x54-740004.3
  8. // Note that the behavior for local initialized variables is different from
  9. // the one of a local typed constant. /A local typed constant behaves like a
  10. // global initialized variable/.
  11.  
  12. // Note: in case documentation refers to behaviour only (e.g. not act as a global
  13. //       variable then why there are /multiple scopes/ for a typed constants?
  14.  
  15. {$define test_foo}  // Enabling generates an error, conflicting with documentation.
  16.                     // test.pas(36,3) Note: Local variable "x" not used
  17.                     // test.pas(43,16) Error: Duplicate identifier "Foo"
  18.                     // test.pas(55,4) Fatal: There were 1 errors compiling module, stopping
  19.  
  20. {.$define test_bar}  // Enabling generates an error in accordance with documentation
  21. type
  22.   TTestClass = class
  23.    public
  24.     procedure Foo;
  25.     procedure Bar;
  26.    end;
  27.  
  28. var
  29.   TestClass: TTestClass;
  30.   {$ifdef test_bar}
  31.   Bar : boolean;
  32.   {$endif}
  33.  
  34. procedure TTestClass.Foo;
  35. const
  36.   x: integer = 0;     // This contradicts the contradiction
  37. begin
  38. end;
  39.  
  40. procedure TTestClass.Bar;
  41. const
  42.   {$ifdef test_foo}
  43.   Foo: integer = 0;
  44.   {$endif}
  45.   {$ifdef test_bar}
  46.   Bar: integer = 0;
  47.   {$endif}
  48.   x: string = 'test'; // This contradicts the contradiction
  49. begin
  50. end;
  51.  
  52. begin
  53.   TestClass := TTestClass.Create;
  54.   TestClass.Free;
  55. end.
  56.  
This messes up my brain (and it was already mush)  :)
« Last Edit: September 26, 2023, 12:08:20 pm by TRon »

Fibonacci

  • Full Member
  • ***
  • Posts: 219
  • #PDK
Re: Confusing scope(s) for typed constant
« Reply #1 on: September 25, 2023, 11:15:30 am »
Looks like you cant have a const with name already used as procedure name.

This makes sense, because if you were able to do it, what "Foo" would be? A const, or a procedure?

TRon

  • Hero Member
  • *****
  • Posts: 1849
Re: Confusing scope(s) for typed constant
« Reply #2 on: September 25, 2023, 11:20:14 am »
@Fibonacci:
Yes, I mistakenly produced the wrong example because of how/why I ran into this. The foo and bar variables should have been named differently from the methods.

Though, as is it is still a pita. I ran into it changing the ancestor of a class I was working on and that caused a compilation failure because in that other ancestor there exist an method named update (which happened to be the same name of my local typed constant in the derived class). Why there not exist a solution to be able to address a variable local to a method. e.g. imho it makes more sense for a local variable to be local to the method and not to the class.

I still wonder what is actually meant with "A local typed constant behaves like a global initialized variable" because practice shows it isn't seen by the compiler as a global variable.
« Last Edit: September 25, 2023, 11:26:40 am by TRon »

Fibonacci

  • Full Member
  • ***
  • Posts: 219
  • #PDK
Re: Confusing scope(s) for typed constant
« Reply #3 on: September 25, 2023, 11:23:33 am »
This reminded me of:

Code: Pascal  [Select][+][-]
  1. someclass = class
  2.   somevar: integer;
  3.   function somefunc(somevar: integer): integer;
  4. end;

You cant use "somevar" as parameter name if that class already has a variable with that name. THIS IS STUPID. In Delphi mode it works.

Edit: Yeah! Found the modeswitch that allows that without setting the mode to Delphi

{$modeswitch DUPLICATELOCALS}

BTW! Your code compiles now  :D :D
« Last Edit: September 25, 2023, 11:30:53 am by Fibonacci »

Fibonacci

  • Full Member
  • ***
  • Posts: 219
  • #PDK
Re: Confusing scope(s) for typed constant
« Reply #4 on: September 25, 2023, 11:40:10 am »
I still wonder what is actually meant with "A local typed constant behaves like a global initialized variable" because practice shows it isn't seen by the compiler as a global variable.

Maybe its about that the variable is kept alive, like a global, but accessible only in function's scope

Code: Pascal  [Select][+][-]
  1. function somefunc: string;
  2. const
  3.   stringy: string = '';
  4. begin
  5.   stringy += '.';
  6.   result := stringy;
  7. end;
  8.  
  9. begin
  10.   writeln(somefunc);
  11.   writeln(somefunc);
  12.   writeln(somefunc);
  13.  
  14.   readln;
  15. end.

'somefunc' will remember 'stringy' value and on each call add another dot to it

TRon

  • Hero Member
  • *****
  • Posts: 1849
Re: Confusing scope(s) for typed constant
« Reply #5 on: September 25, 2023, 11:40:26 am »
This makes sense, because if you were able to do it, what "Foo" would be? A const, or a procedure?
Ofc. it makes sense  :). But the ambiguity for (at least) that (specific case) can be solved by using Self to refer to the class/object.

'somefunc' will remember 'stringy' value and on each call add another dot to it
It is exactly that behaviour that makes me use it (on occasion)  :D

It is perhaps because English isn't native for me that I interpret that part of the documentation as "behave and act acting like a global variable" thereby probably missing the nuance of "behaves".

« Last Edit: September 25, 2023, 11:44:50 am by TRon »

Fibonacci

  • Full Member
  • ***
  • Posts: 219
  • #PDK
Re: Confusing scope(s) for typed constant
« Reply #6 on: September 25, 2023, 11:44:09 am »
This makes sense, because if you were able to do it, what "Foo" would be? A const, or a procedure?
Ofc. it makes sense. But the ambiguity for (at least) that (specific case) can be solved by using Self to refer to the class/object.

And in mode Delphi it works exactly like that. Alternative solution is using the modeswitch DUPLICATELOCALS, which IMHO should be default on for mode ObjFpc

TRon

  • Hero Member
  • *****
  • Posts: 1849
Re: Confusing scope(s) for typed constant
« Reply #7 on: September 25, 2023, 12:26:25 pm »
And in mode Delphi it works exactly like that. Alternative solution is using the modeswitch DUPLICATELOCALS, which IMHO should be default on for mode ObjFpc
I can confirm that it works in mode Delphi (as expected) but the duplicatelocals modeswitch doesn't seem to do the trick for me. Tried other modeswitches as well (at least those that seem relevant) to no avail.

btw: Thank you for the response as my initial posted example more or less missed the point.

edit: figured it out. It requires trunk for that to work. Thank you !
« Last Edit: September 25, 2023, 12:37:00 pm by TRon »

tetrastes

  • Sr. Member
  • ****
  • Posts: 425
Re: Confusing scope(s) for typed constant
« Reply #8 on: September 25, 2023, 01:02:03 pm »
I still wonder what is actually meant with "A local typed constant behaves like a global initialized variable" because practice shows it isn't seen by the compiler as a global variable.

I think here this means that it is initialized only once. The author of doc forget about different scope. It is analogue of static variable in C.

TRon

  • Hero Member
  • *****
  • Posts: 1849
Re: Confusing scope(s) for typed constant
« Reply #9 on: September 26, 2023, 12:08:06 pm »
Indeed it seems that author forgot about scope (or that you are not suppose to include/add that yourself when reading the statement from the docs). I get it now thanks to you both.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5281
  • Compiler Developer
Re: Confusing scope(s) for typed constant
« Reply #10 on: September 28, 2023, 10:07:39 pm »
And in mode Delphi it works exactly like that. Alternative solution is using the modeswitch DUPLICATELOCALS, which IMHO should be default on for mode ObjFpc

No, the modeswitch is not default in the FPC and ObjFPC mode by design to avoid issues due to scope shadowing (and these issues do happen).

 

TinyPortal © 2005-2018