Forum > FPC development
[solved] Confusing scope(s) for typed constant
TRon:
Code speaks louder than words:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program test; {$mode objfpc}{$H+} // documentation:// - https://www.freepascal.org/docs-html/ref/refse23.html// - https://www.freepascal.org/docs-html/current/ref/refse23.html#x54-740004.3// Note that the behavior for local initialized variables is different from// the one of a local typed constant. /A local typed constant behaves like a// global initialized variable/. // Note: in case documentation refers to behaviour only (e.g. not act as a global// variable then why there are /multiple scopes/ for a typed constants? {$define test_foo} // Enabling generates an error, conflicting with documentation. // test.pas(36,3) Note: Local variable "x" not used // test.pas(43,16) Error: Duplicate identifier "Foo" // test.pas(55,4) Fatal: There were 1 errors compiling module, stopping {.$define test_bar} // Enabling generates an error in accordance with documentationtype TTestClass = class public procedure Foo; procedure Bar; end; var TestClass: TTestClass; {$ifdef test_bar} Bar : boolean; {$endif} procedure TTestClass.Foo;const x: integer = 0; // This contradicts the contradictionbeginend; procedure TTestClass.Bar;const {$ifdef test_foo} Foo: integer = 0; {$endif} {$ifdef test_bar} Bar: integer = 0; {$endif} x: string = 'test'; // This contradicts the contradictionbeginend; begin TestClass := TTestClass.Create; TestClass.Free;end. This messes up my brain (and it was already mush) :)
Fibonacci:
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:
@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.
Fibonacci:
This reminded me of:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---someclass = class somevar: integer; function somefunc(somevar: integer): integer;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
Fibonacci:
--- Quote from: TRon on September 25, 2023, 11:20:14 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.
--- End quote ---
Maybe its about that the variable is kept alive, like a global, but accessible only in function's scope
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function somefunc: string;const stringy: string = '';begin stringy += '.'; result := stringy;end; begin writeln(somefunc); writeln(somefunc); writeln(somefunc); readln;end.
'somefunc' will remember 'stringy' value and on each call add another dot to it
Navigation
[0] Message Index
[#] Next page