4

I tried to set array size with const member variable like below

class A {
  const int SIZE;

  A() : SIZE(10) {}
  void aaa() { int a[SIZE]; }
};

I cannot build

a[SIZE]

like this expression.

When I use GCC, build success. But when I use VC++ (Windows), I cannot build.

The error message is "'this' cannot be used in a constant expression"

How to set array size with const member variable?

7
  • stackoverflow.com/questions/39334435/… Commented Jan 18, 2019 at 2:38
  • 1
    C++ need to know array sizes at compile time. Consider making your array size into a template parameter instead of a class member. Commented Jan 18, 2019 at 2:52
  • SIZE variable is const variable but member variable. I already check to build with this expression in gcc. However only Visual C++ compiler cannot build with this expression. Commented Jan 18, 2019 at 2:56
  • Can you initialize the constant on the line const int SIZE = 10; ? Commented Jan 18, 2019 at 3:33
  • 1
    SIZE is not a constant expression (it is just a const qualified int). If you’re using newer c++ standard versions, you can declare it to be constexpr instead of const and initialize it inline (constexpr int SIZE = 10;). Commented Jan 18, 2019 at 4:21

3 Answers 3

3

Variable Length Arrays

when I use VC++ (Windows), I cannot build.

An array int a[SIZE] is created on stack with automatic storage duration. Then this SIZE usually must be determined at compile-time in C++. But your SIZE is defined without a value as follows:

const int SIZE;

Thus compilers can not know it's value at compile-time and would show compilation error. So your SIZE is a dynamic variable.

When I use GCC, build success.

...But some C++ compilers support VLA (variable length arrays) which is a C99 addition and allows declaring C-style arrays on stack with a dynamic length. VC++ does not support C99 and VLA, but GNU compiler supports VLA as an extension even in C90 and C++. This is the reason why you can compile the above code by GCC without errors.

If you add -pedantic (-pedantic-errors) option to gcc compile command, we can get warnings (errors) for most gcc extensions. In this case, with this option we should get warning (error) message: ISO C++ forbids variable length array 'a'.


How to fix the current error ?

(1) If you want to use C-style arrays, one way is making SIZE a macro as follows. Then compilers can know it's value at compile-time:

#define SIZE 10

class A
{
public:
  A() {}
  void aaa() { int a[SIZE]; }
};

(2) Defining the value of SIZE as a static const variable in the class definition, then compilers again can know it's value at compile-time:

class A
{
  static constexpr int SIZE = 10;

public:
  A() {}
  void aaa() { int a[SIZE]; }
};

(3) C++ provides array functionality by std::vector and std::array which might make our code more readable, portable and robust. I expect that std::array on stack would be more efficient than std::vector in your case, because 10 ints need less memory and std::array is allocated on stack just only once without causing problems. This is a solution with std::array:

#include <array>

class A
{
  static constexpr int SIZE = 10;

public:
  A() {}
  void aaa() { std::array<int, SIZE> a; }
};
Sign up to request clarification or add additional context in comments.

Comments

0

Well, SIZE is probably not a macro because, here, you initialize it with 10 and have it as a variable. If it was a macro, your expression int a[SIZE] would work but you would not need lines 2-4 anyways.

If SIZE is, as here, a normal variable (which includes dynamically creating A with a size parameter, although the input might be from a macro), you should use a vector.

#include <vector>

class A {
  const int SIZE;

  A() : SIZE(10) {}
  void aaa() { std::vector<int> a(SIZE); }
};

Usage of a is now the same.

Comments

0

If you are using an older compiler pre c++11, e.g c++03 you can also do enum {SIZE=10};

class A {
  enum {SIZE=10};

  void aaa() {int a[SIZE];}
};

Comments

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.