type
TTest = record
x: Integer;
end;
procedure Foo(x: Integer);
var
t: TTest;
begin
with t do
x := 42; // t.x shadows param x
end;
Shadowing means overriding some identifier with another one. Sometimes shadowing can be disambiguated, e.g. when one unit shadows definitions of another unit you can write unit1.x to disambiguate.
First, what you are calling "shadowing" is normally referred to as _masking_.
Free Pascal does not allow shadowing without disambiguation, e.g. the following is not allowed.for.exactly that reason:
procedure foo(x: Integer);
var
x: Double;
begin
end;
With statements allow to shadow symbols without disambiguation (as in the example above), which is why it's bad.
You really need to learn basic compiler construction theory. In that code there is no masking (or shadowing as you call it), what there is, is a _duplicate_ identifier. No correctly implemented compiler would allow that code because the parameter "x" and the local variable "x" are in the _same_ scope, therefore they cannot use the same name.
It's so bad that languages that used to have with, like JavaScript, deprecated it, because it's a syntactic concept that's born out of pure laziness, gives no semantic benefits but due to shadowing can introduce errors.
Yes, allowing duplicate identifiers is so bad that no correctly implemented compiler allows it. Duplicate identifiers have been "deprecated" since the birth of compilers and interpreters.
Imagine a world in which you can't change any result of a function, then the following would also not work:
In this example t is the result of a function but is changed outside the function. Oh no hell breaks lose, how can this be acceptable!!!!
Nice try but "t" is most definitely NOT the result of a function. "t" is where the result of the function is copied to. That's VERY different. The result of the function is NOT being changed, the location where the result of the function has been COPIED to is being changed.
OTH, FPC is allowinjg this atrocity (which you are trying to hide with the above code which is very different):
program Project1;
type
TTest = record
V: Integer;
end;
var
X: TTest;
function Test: TTest;
begin
Result := X;
end;
var
T: TTest;
begin
with Test do
V := 1; //No Error
Test.V := 1; //Error: Argument cannot be assigned to
end.
Line 20 is _changing_ the result of the function because line 20 is semantically identical as line 21 but FPC _incorrectly_ considers them different which is an _atrocity_.
But I mean you do not know what shadowing is, which is absolutely basic knowledge about programming language design, so I guess there is no real reason to continue to argue
Let's engage in "basic knowlege"... it's not called "shadowing" (at least not by those who know a little compiler theory), it's called masking. if you need confirmation of that, write a C program that masks one variable or parameter and you'll get a hint or warning telling you that some variable is _masking_ another one.
BUT, please, do prove me wrong... find a mainstream compiler that refers to a masked variable as a shadowed variable.
I _strongly_ suggest you learn basic compiler construction theory. I highly recommend the book "Per Brinch Hansen On Pascal Compilers" (unfortunately, that book does not cover the "with" statement), another really good educational compiler is Per Brinch Hansen's SuperPascal (source available online) and I also strongly recommend you read "The P4 Compiler and Interpreter
by Steven Pemberton, Amsterdam, and Martin Daniels", text is available onlne at:
http://pascal.hansotten.com/uploads/pemberton/homepages.cwi.nl/_steven/pascal/book/pascalimplementation.htmlAfter you've learned basic compiler theory, we can resume the discussion about the "with" statement.
Have fun reading and please learn.