5

Consider this trivial test code:

class Test
{
public:
   Test() {/* empty */}

private:
   enum {BLAH = 42};

   static constexpr int Magic() {return BLAH*4;}

   float f[Magic()];
};

int main(int argc, char ** argv)
{
   Test t;
   return 0;
}

When I try to compile it (under MacOS/X using clang++ from the latest XCode), I get this compiler error:

Jeremys-Mac-Pro:~ jaf$ clang++ -std=c++11 ./test.cpp
./test.cpp:11:14: error: fields must have a constant size: 'variable length
      array in structure' extension will never be supported
       float f[Magic()];

Can anyone explain why this is an error? For comparison, if I move the Magic() method out of the Test class and make it a free-standing function, it compiles as expected, but I don't really want to do that because I want to keep Magic() and BLAH private to the Test class if possible.

(Note: I'm not trying to use variable-length arrays here; rather I'm trying to declare an array whose size is determined by the computation of a function at compile-time)

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234

1 Answers1

3

It's because functions within a class aren't processed until the class is complete. This rule allows a function defined within a class to access members of that class that are defined later in the class than that function. As a result, Magic() does not yet have a definition, so can't be evaluated at that moment of compile time.

This is correct behavior, though the error the various compilers generate are not helpful for understanding the problem.

The formal rules are in the C++ standard at [class.member]/6:

A class is considered a completely-defined object type (6.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

Myria
  • 3,372
  • 1
  • 24
  • 42