www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Accessing function frame from struct

reply Sebastien Alaiwan <ace17 free.fr> writes:
Hi guys,
here's my full code below.
My problem is that last "auto Y = X" assignment, that the 
compiler won't accept:

yo.globalFunction.DirectStruct.IndirectStruct.indirectMemberFunc 
cannot access frame of function yo.globalFunction

I was expecting X to be accessible from here.
Suprisingly, if I replace all "struct" with "class", the last 
assignment is accepted by the compiler.
Could someone please tell me why the scoping asymmetry between 
structs and classes?

void globalFunction()
{
   auto X = 0;

   struct DirectStruct
   {
     void directMemberFunc()
     {
       auto Y = X; // OK, X is accessible

       struct HybridStruct
       {
         void hybridFunc()
         {
           auto Y = X; // OK, X is accessible
         }
       }
     }

     struct IndirectStruct
     {
       void indirectMemberFunc()
       {
         auto Y = X; // Error: can't access frame of globalFunc
       }
     }
   }
}
Jun 25 2017
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/25/2017 06:01 AM, Sebastien Alaiwan wrote:
 Hi guys,
 here's my full code below.
 My problem is that last "auto Y = X" assignment, that the compiler won't
 accept:

 yo.globalFunction.DirectStruct.IndirectStruct.indirectMemberFunc cannot
 access frame of function yo.globalFunction

 I was expecting X to be accessible from here.
 Suprisingly, if I replace all "struct" with "class", the last assignment
 is accepted by the compiler.
 Could someone please tell me why the scoping asymmetry between structs
 and classes?
I don't know why the asymmetry but that's how it is but the following explanation would be acceptable to me.
 void globalFunction()
 {
   auto X = 0;

   struct DirectStruct
   {
     void directMemberFunc()
     {
       auto Y = X; // OK, X is accessible

       struct HybridStruct
       {
         void hybridFunc()
         {
           auto Y = X; // OK, X is accessible
         }
       }
     }

     struct IndirectStruct
     {
       void indirectMemberFunc()
       {
         auto Y = X; // Error: can't access frame of globalFunc
       }
     }
   }
 }
IndirectStruct is not a nested struct; rather, just a type defined inside DirectStruct. So, anybody can simply use it on its own without a DirectStruct object around. (Yes, there is a name-access issue in this example but it doesn't change the fact that IndirectStruct is just a type defined by DirectStruct.) Commenting out the offending line and returning an IndirectStruct: auto globalFunction() { auto X = 0; struct DirectStruct { void directMemberFunc() { auto Y = X; // OK, X is accessible struct HybridStruct { void hybridFunc() { auto Y = X; // OK, X is accessible } } } struct IndirectStruct { void indirectMemberFunc() { // Commenting out... // auto Y = X; // Error: can't access frame of globalFunc } } } // Making and returning an IndirectStruct without any associated // DirectStruct as its outer object: return DirectStruct.IndirectStruct(); } void main() { auto a = globalFunction(); // Able to use an IndirectStruct directly: a.indirectMemberFunc(); } On the other hand, HybridStruct is a nested struct because it does have an outer scope: the body of directMemberFunc(). Again, I don't know why classes are different. Ali
Jun 26 2017