From a scope block, the syntax for accessing a duplicated symbol defined in a namespace/UDT is captured by the local symbol, making impossible the desired access.
Simple example with a procedure inside a namespace:
Namespace NS
Dim x As Integer = 3
Sub S ()
Dim x As Integer = 4
Print "From Sub() in Namespace 'NS', access to 'NS.x' is captured by local 'x'"
Print "x="; x, "NS.x="; NS.x
End Sub
End Namespace
NS.S()
Sleep
Output:
From Sub() in Namespace 'NS', access to 'NS.x' is captured by local 'x'
x= 4 NS.x= 4
More complex example with 3 different failing cases:
member procedure inside UDT
Dim Shared x As Integer = 1
Type UDT
Dim As Integer dummy
Static As Integer x
Declare Static Sub S ()
End Type
Dim As Integer UDT.x = 2
Namespace NS
Dim x As Integer = 3
Sub S ()
Dim x As Integer = 4
Print "From Sub() in Namespace 'NS', access to 'NS.x' is captured by local 'x'"
Print "x="; x, "NS.x="; NS.x, "UDT.x="; UDT.x, ".x="; .x
End Sub
End Namespace
Sub S ()
Dim x As Integer = 4
Print "From Sub() in Global Namespace '.', access to '.x' is captured by local 'x'"
Print "x="; x, "NS.x="; NS.x, "UDT.x="; UDT.x, ".x="; .x
End Sub
Static Sub UDT.S ()
Dim x As Integer = 4
Print "From Sub() in Type 'UDT', access to 'UDT.x' is captured by local 'x'"
Print "x="; x, "NS.x="; NS.x, "UDT.x="; UDT.x, ".x="; .x
End Sub
NS.S()
Print
S()
Print
UDT.S()
sleep
Output:
From Sub() in Namespace 'NS', access to 'NS.x' is captured by local 'x'
x= 4 NS.x= 4 UDT.x= 2 .x= 1
From Sub() in Global Namespace '.', access to '.x' is captured by local 'x'
x= 4 NS.x= 3 UDT.x= 2 .x= 4
From Sub() in Type 'UDT', access to 'UDT.x' is captured by local 'x'
x= 4 NS.x= 3 UDT.x= 4 .x= 1
Check if there is not a link with #581 Locals break/override THIS access to inherited members
Indeed, I think [#581] is caused by this.
Perhaps this could be fixed by making each scope have its own namespace - but that's a massive change to fbc's symbol tables, that will surely have a negative impact on scope creation & symbol lookup performance, or will even require lots of the code to be rewritten.
Related
Bugs:
#581Indeed, first glance there is a temptation to rewrite the symbol database, but that would probably take months. Digging deep in to the compiler internals, I have come up with 2 underlying causes which could be improved incrementally:
I'm working on a pull request to address these 2 issues for shared variables (and arrays) that starts the effort to do 2 things:
The linked #581 "Locals break/override THIS access to inherited members" is less troublesome because exists a simple workaround that is to access with BASE.[BASE.]...
At opposite, faced with this bug above, there is only one possibility of workaround to access the real value of "UDT.x". This is: "Cast(UDT Ptr, 0)->x".
No workaround for others (except differentiate the symbol names!).
Last edit: fxm (freebasic.net) 2014-11-11
Another variant:
In the following example, not only does the local array 'd ()' hide the global variable 'd', but also captures the data-type of the global variable for its own data-type if it is not specified in 'redim ...':
Similar behavior:
[edit]
Behavior normal with overload procedures, because by default, the first is choosen.
Can be solved with:
Print ProcPtr(UDT.test, Sub(Byref As UDT))Last edit: fxm (freebasic.net) 2021-09-27
Fixed / changed by pull request sf.net # 645 - namespace and scope resolution on variables #346 (github.com)
Commit: [ec1e19665cdf3153e058cda5722689ad3fe51ee8]
Related
Commit: [ec1e19]