December 06

The two little demo scripts:

string mxnAdd()(string strName) {

   return `(typeof(` ~ strName ~ `) Pld) {

      import core.stdc.stdlib : malloc;

      struct Mst {
         typeof(` ~ strName ~ `) Pld;
         int I1;
      }
      Mst*    MstPtr;


      MstPtr = cast(Mst*)(malloc(Mst.sizeof));
      if (MstPtr is null) {
         return null;
      } else {
      }

      MstPtr.Pld    = Pld;
      MstPtr.I1 = 1;
      return &MstPtr.Pld;
   }(` ~ 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.
}


and

string mxnAdd()(string strName) {

   return `(typeof(` ~ strName ~ `) XVar) {

      import core.stdc.stdlib : malloc;

      struct Mst {
         typeof(` ~ strName ~ `) XVar;
         int I1;
      }
      Mst*    MstPtr;


      MstPtr = cast(Mst*)(malloc(Mst.sizeof));
      if (MstPtr is null) {
         return null;
      } else {
      }

      MstPtr.XVar    = XVar;
      MstPtr.I1 = 1;
      return &MstPtr.XVar;
   }(` ~ 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.
}


Are identical, except that, in the second demo, one variable name in the mixin function
was changed to be the same as a variable name in the main function
(it would obviously be dangerous to do this deliberately, but this happened by accident).

The first demo runs OK.

The second fails with a 'circular reference' error.

My question is simply why this is a problem at all - the scope of any names used in
the mixin function should surely not extend beyond that function, so no clash should arise?