Why aren't static data members allowed in local classes?

12.9k views Asked by At

What is the reasoning to why static const members cannot exist in local classes? It seems like a rather silly restriction.

Example:

void foo() {
  struct bar {
    int baz() { return 0; }   // allowed
    static const int qux = 0; // not allowed?!?
  };
}

struct non_local_bar {
  int baz() { return 0; }   // allowed
  static const int qux = 0; // allowed
};

Quote from standard (9.8.4):

A local class shall not have static data members.

4

There are 4 answers

1
Gerald On BEST ANSWER

From the standard section 9.4.2:

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression. In that case, the member can appear in integral constant expressions within its scope. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

Basically, local classes have no linkage, and static data members require a linkage.

Since there's no way to define a static data member of a local class in namespace scope (a declaration with an initializer is not a definition), they are not allowed, whether they are of const integral type or not. On the surface it may seem like the compiler should just be able to inline the value, but then what happens if you try to access a pointer to the member? With namespace scoped classes you'd just get a linker error, but local classes have no linkage.

I guess in theory they could just allow you to use static const integral types in local classes as long as they are only used in integral constant expressions, but it would probably just put too much of a burden on the standards body and compiler vendors to differentiate for very little practical value; local static variables are accessible from local classes, so using a local static const should be just as good.

3
Hemant Metalia On

Static members of a class need to be defined in global scope, e.g.

  abc.h

   class myClass {
   static int number;
  };
     abc.cpp

   int myClass::number = 314;

Now, since the scope inside void abc(int x) is not global, there is no scope to define the static member.

0
Johannes Schaub - litb On

I dont think there is a.reason. Normal static datamembers are disallowed because there is no way to define them after being declared.

Also dont forget you can create a local const variable outside the.class that you can use inside the class as long as you only read its value (that is, as long as you dont take.its.address).

0
Alexis Wilke On

As things progress, we now have C++11 and with that you can define integral constants variable members in your classes.

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

That works when you compile with C++11. Notice that the static keyword is not used. When compiling with optimizations turned on, those variables will likely all get optimized out. In debug, though, they appear in your structure as regular variable members.

Note, however, that the size of the class/structure will still include that variable. So here it is likely 4 bytes for the variable FOO.

However, in most cases, classes defined in a function will completely be optimized out so this is a great way of doing things (a good 50% of my classes have such variable members!)