June 25, 2017
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
      }
    }
  }
}


June 26, 2017
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