tags:

views:

358

answers:

6

I know we cannot declare a static member variable inside a local class... but the reason for it is not clear.

So please can anybody explain it?

Also, why can't we access a non-static variable define inside the function, within which the local class has been defined,directly in the local class member functions?

In the code given below:

int main(int argc, char *argv[])
{
    static size_t staticValue = 0;

    class Local
    {
         int d_argc; // non-static data members OK
         public:
         enum // enums OK
         {
             value = 5
         };
         Local(int argc) // constructors and member functions OK
         : // in-class implementation required
          d_argc(argc)
         {
               // global data: accessible
               cout << "Local constructor\n";
               // static function variables: accessible
               staticValue += 5;
         }
         static void hello() // static member functions: OK
         { 
            cout << "hello world\n";
         }
   };
   Local::hello(); // call Local static member
   Local loc(argc); // define object of a local class.
   return 0;
}

Static variable staticValue is directly accessible while on the other hand argc argument from main is not....

+2  A: 

Local classes don't have full access to their enviroment (thanks Richard)... you have to use e.g. references or pointers to work around that:

void f() {
    int i = 0;

    struct local {
        int& i;
        local(int& i) : i(i) {}
        void f() { i = 1; }
    };

    local l(i);
    l.f();
    assert(i==1);
}
Georg Fritzsche
Local classes do have access to static variables in the function. You don't need the reference.
Richard Pennington
Thanks, for some reason i never realized that.
Georg Fritzsche
A: 

Static variables are initialized when program starts. Local classes are loaded when method is called. And unloaded when method call ends.

According to Wikipedia

In computer programming, a static variable is a variable that has been allocated statically — whose lifetime extends across the entire run of the program.

This is in contrast with loading and unloading of local classes having static variables declared

Xinus
+4  A: 

The two questions are related. I believe the answer is not clear to you because the static keyword in C++ has overloaded meanings.

When you define a static variable inside the function, you're really telling the compiler to initialize it only in the first call (so you can use the value across multiple calls). This is not exactly the same of the case of a file-scope or class-scope static variable.

With this in mind it might not make sense to define a static variable inside a local class, which is in turn defined inside a function.

Regarding your second question, a local class actually can access static variables defined its enclosing function. The code below, for example, should compile in an standard conformant compiler.


void f()
{
  static int i;
  class local
  {
    int g() { return i; }
  };

  local l;
  /* ... */
}

int main()
{
  f();
  return 0;
}
ltcmelo
i wrongly phrased teh question , sorry for that.i meant to ask about the non static member which are not directly accessible inside local class
ishan
A: 

I think the reason that local classes can't have static members (or functions defined outside of the class) is more for syntactical than semantic reasons. Static members could be implemented just as in non-local classes: The static would have the lifetime starting at the first call to a function, just as static variables declared inside a function do. The compiler would have to make sure the static members were initialized when the first instance of the class was created.

Imagine the problem with name mangling now that the enclosing function signature becomes part of the name. ;-)

The reason you can't access local variables or parameters of a function in a local class is that it would complicate the code required to implement the class with little gain. The non-static members of a class are typically accessed via the "this" pointer or pointer to the specific instance. To access variables and parameters local to the enclosing function would require some mechanism to make them accessible. That mechanism might be fairly trivial if the functions were inlined, but what happens when they are not?

Richard Pennington
I think there are semantic reasons -- see my answer.
Dan Breslau
@Dan: I agree about the local variable access (see my third paragraph), I was talking about local static members.
Richard Pennington
Yes, I misread your response. Sorry.
Dan Breslau
+3  A: 
Nikolai N Fetissov
Local objects can be defined within the function body, but they cannot leave the function as objects of their own type. I.e., a local class name cannot be used for either the return type orfor the parameter types of its surrounding function.However, as a prelude to inheritance a local class may be derived from an existing class allowing the surrounding function to return a dynamically allocated locally constructedclass object, pointer or reference could be returned via a base class pointer or reference
ishan
Isn't that what I said?
Nikolai N Fetissov
+1  A: 

Another reason why you can't examine stack variables in the enclosing scope is that a function in the local class isn't necessarily called directly from the enclosing function.

In the example below, life would be easy if hello() were the only function in the class: To find the variable stackValue, hello() would simply need to look into its caller's stack frame. But here, I've introduced Local::goodbye(), which may or may not invoke Local::hello. In this case, how would Local::hello() know where to find the enclosing function's stack frame? (We'd need closures to make this work. I love closures, but I can't see that happening in C++.)

int main(int argc, char *argv[])
{
    static size_t staticValue = 0;
    int size_t stackValue = argc;

    class Local
    {
         void hello() 
         { 
            cout << "stackValue is " << stackValue << "\n";
         }
         void goodbye()
         {
            if (stackValue == 42) {
                hello();
            }
            else {
                cout << "Goodbye!\n";
            }
         }
   };
   Local loc;
   loc.hello();
   stackValue = 42;
   loc.goodbye();
   return 0;
}
Dan Breslau