// The code below is believed valid, but fails compilation with a circular
// reference error.
// If the string 'XVar' in mxnAdd is replaced with another string valid for a
// variable (I used 'Pld'), in all the places marked 'Here',
// the code compiles and runs ok.
// I don't support the double-use of the same name (cropped up by accident)
// but the code does seem unambiguous (if confusing), and does not
// seem to break scope rules.
string mxnAdd()(string strName) {
return `(typeof(` ~ strName ~ `) XVar) { // Here
import core.stdc.stdlib : malloc;
struct Mst {
typeof(` ~ strName ~ `) XVar; // Here
int I1;
}
Mst* MstPtr;
MstPtr = cast(Mst*)(malloc(Mst.sizeof));
if (MstPtr is null) {
return null;
} else {
}
MstPtr.XVar = XVar; // Here twice
MstPtr.I1 = 1;
return &MstPtr.XVar; // Here
}(` ~ strName ~ `)`;
}
void main() {
// Compile-time.
// Establish simple variables:
int IntFld1;
int IntFld2;
// Define a structure:
struct X {
int Fld1;
int Fld2;
}
// Establish a structure variable:
X XVar;
// Establish a pointer to the structure:
X* XPtr;
// Execution-time.
// Load variables:
IntFld1 = 3;
IntFld2 = 4;
// Load the structure variable members:
XVar.Fld1 = IntFld1;
XVar.Fld2 = IntFld2;
// Now execute the command:
XPtr = mixin(mxnAdd("XVar"));
// Now check the results:
assert(XPtr !is null); // Returned pointer non-null,
// so shows new datastructure added.
assert(XPtr.Fld1 == 3); // Shows new datastructure holds original data item.
assert(XPtr.Fld2 == 4); // Shows new datastructure holds original data item.
}
Comment #1 by dkorpel — 2023-12-07T17:14:33Z
Reduced example:
```D
int XVar;
struct Mst
{
typeof(XVar) XVar;
}
```
The issue seems that `typeof(XVar)` is resolved after adding `XVar` to the symbol table of `Mst`. I wonder if that's done deliberately to make something else work.
Comment #2 by dfj1esp02 — 2023-12-08T19:40:55Z
The problem usually happens as:
alias int XVar;
struct Mst
{
XVar XVar;
}
As you can see there's an ambiguity who is who.
Usually it's possible to disambiguate with FQN:
struct Mst
{
.XVar XVar;
}
Stack variables have no FQN, so give them a different name
alias XVar XVar2;
struct Mst
{
typeof(XVar2) XVar;
}
Comment #3 by bmqawsed4 — 2023-12-09T17:18:09Z
(In reply to anonymous4 from comment #2)
> The problem usually happens as:
>
> alias int XVar;
> struct Mst
> {
> XVar XVar;
> }
>
> As you can see there's an ambiguity who is who.
> Usually it's possible to disambiguate with FQN:
>
> struct Mst
> {
> .XVar XVar;
> }
>
> Stack variables have no FQN, so give them a different name
>
> alias XVar XVar2;
> struct Mst
> {
> typeof(XVar2) XVar;
> }
Unfortunately I do not see any ambiguity in my original code.
It _is_ confusing (the situation of the same name being used both in the main function and the sub-function was an accident, not intentional).
But I cannot see what rule of D has been broken.
To me, if nothing else, D's scope rules should have stopped any problems.
Comment #4 by robert.schadek — 2024-12-13T19:32:06Z