0

I have a class with a member function which declares an array whose size is based off a formula.

template <int SIZE>
class Example{
   constexpr int lookup(const int n) const
   {
      return n * n + n;
   }
   inline void func()
   {
       double array[lookup(SIZE)];
   }
};

This gives me the vla error. I think it should work because SIZE is resolved at compile time, and lookup is a constexpr. I know the following will work:

template <int SIZE>
class Example{

   inline void func()
   {
       constexpr int sz = SIZE * SIZE + SIZE;
       double array[sz];
   }
};

I guess I'm just trying to figure out why

EDIT Sorry for the typos, was trying to just write a smaller example and ended up with the missing n and class name.

3
  • 4
    Where is n coming from? Commented May 15, 2020 at 14:46
  • 1
    With a few small syntax fixes, it complies and runs fine: repl.it/repls/WanLavishComputergames Commented May 15, 2020 at 14:47
  • 1
    @BillLynch - compile and run fine but isn't standard C++; if you add "-pedantic", you get the warning "warning: variable length arrays are a C99 feature". Commented May 15, 2020 at 17:05

2 Answers 2

3

It's complicated...

First of all, some compilers (see MikeCAT answer and Bill Lynch linked example) can compile the following code (if you give a name to the class and correct lookup() naming n the argument)

inline void func()
{
    double array[lookup(SIZE)];
}

because they support a C99 extension that accept the "variable length array" feature.

But this extension isn't standard C++.

You can verify this modifying func() as follows (almost equivalent, in standard C++)

inline void func()
{
    constexpr int s = lookup(SIZE);

    double array[s];
}

and this can't compile if lookup() is a non-static method

Consider that

 lookup(SIZE);

is a short form for

 this->lookup(SIZE);

I mean... the use of lookup() involve an object of your class.

The problem is that your func() method is available for both constexpr and non-constexpr objects.

Suppose you have a non-constexpr object: calling func() from it you impose that

constexpr int s = this->lookup(SIZE);

is evaluated compile-time.

That is: you impose that the this pointer (so the object itself) is available compile-time.

This is clearly impossible for run-time created objects, so your code can't compile.

Different if you declare lookup() as a static method: this way, calling lookup() doesn't involve an object of your class so your code can compile.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for sifting through my typos to see what I was trying to ask!
0
  • Class template must have a name.
  • n is not declared in lookup.

This should work as C++11:

template <int SIZE>
class hoge { // add hoge
   constexpr int lookup(const int n) const // add n
   {
      return n * n + n;
   }
   inline void func()
   {
       double array[lookup(SIZE)];
   }
};

2 Comments

Uhmmm... I don't think should works. If you add a hoge<2> h; h.func() (maybe declaring func() as public:) and compile with -ansi -padantic with clang++ or g++, you get a "warning: variable length arrays are a C99" (clang++) or "warning: ISO C++ forbids variable length array" (g++). If you add a row constexpr int s = lookup(SIZE); in func(), you get an error.
Ehmmm... sorry... in my preceding comment... -pedantic, not -padantic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.