6
class armon
{
    static const int maxSize=10;    

    int array[maxSize];

    int count=0;

    int* topOfStack=array;
}

Why does maxSize need to be static for it to be used inside array?

quantdev
  • 23,517
  • 5
  • 55
  • 88
Armon Safai
  • 175
  • 9

3 Answers3

12

It doesn't have to be static, but it must be a constant expression.

C++ Standard § 8.3.4 [dcl.array] (emphasis mine) :

If the constant-expression (5.19) is present, it shall be a converted constant expression of type std::size_t and its value shall be greater than zero


That is, the following is also valid :

constexpr std::size_t Size()  { return 10; }; 

struct Y
{
    int array[Size()];
};

Note:

Since the compiler needs to know the size of the class, you cannot do this :

struct Y
{
    const int size = 10;
    int array[size];
};

Possibly making different instances of Y having different sizes.

Also note that in this context, int array[size] is not a constant expression, because it makes use of this, see the C++ standard section § 5.19 [expr.const] :

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

this (5.1.1), except in a constexpr function or a constexpr constructor that is being evaluated as part of e;

(the evaluation of size is really this->size)

Community
  • 1
  • 1
quantdev
  • 23,517
  • 5
  • 55
  • 88
  • this is due to the fact that the compiler is able to reserve memory during compilation. A good explanation [here](http://stackoverflow.com/questions/21350478/what-does-memory-allocated-at-compile-time-really-mean) – lifeOfPI Sep 04 '14 at 09:42
  • You also need to explain why `const int maxSize = 10;` is not considered to give a constant expression, but `static const int maxSize = 10` is – M.M Sep 04 '14 at 10:03
  • @MattMcNabb sure, note added – quantdev Sep 04 '14 at 10:15
  • Next question, given that there is not actually a `Y() : size(5) {}` why shouldn't `size` be a constant expression in that case? – M.M Sep 04 '14 at 10:17
  • @MattMcNabb see my second edit, it is **not** a constant expression ( § 5.19 ) – quantdev Sep 04 '14 at 10:22
  • @quantdev I mean, why doesn't the standard say that `const int size = 10;`, where it is not overruled by a constructor init list, is a constant expression. I guess there was no demand for such a feature. – M.M Sep 04 '14 at 10:25
5

There are two aspects to this question

Aspect 1

C++ array is of fixed size, the size of which needs to be known during compile time. If the decision needs to be deferred during runtime, the array expression becomes ill-formed.

Aspect 2

Declaring a member variable as non-static makes it an instance variable, the value of which only exist once the object is instantiated which is done during run-time. A static variable is a class variable, the value of which can be determined during compile time.

Your particular example becomes the classic chicken-egg paradox.

class armon
{
    static const int maxSize=10;    

    int array[maxSize];

}
  • In order to instantiate your class armon, you need to know its size.
  • In order to know its size, you need to know the size of individual members. In your particular case, you need to know the size of the array.
  • In order to know the size of the array, you need to know the value of the dependent variable maxSize.
  • In order to access the dependent variable maxSize you need to instantiate the class armon.
  • In order to instantiate your class armon, you need to know its size.

So, your array size dependent variable should be a constant expression, which in your particular case should be a static variable,

Abhijit
  • 62,056
  • 18
  • 131
  • 204
1

It doesn't have to be static, it has to be constant.

When you declare a constant inside a class you will be making a constant for each instance of the class.

Also if your maxSize is just const you would have to intialize it in the constructor initializer list because const maxSize is treated as variable whose value you can't change.

Inside a class const keyword means "This is a constant during the hole lifetime of this object". Different objects of the same class can have different values for that constant.

But when it is a static constant there will be only one constant for all instances of the class. This means that you have to initialize constants value on the same line where you are defining it.

  • "if your maxSize is just const you would have to intialize it in the constructor initializer list " is wrong! It can also be a scoped variable that has not to be initialized in initializer list. "Inside a class const keyword means "This is a constant during the hole lifetime of this object"" is also wrong. It is just a "hint" to the programmer. Think about `const_cast<>` – lifeOfPI Sep 04 '14 at 09:48
  • 2
    @lifeOfPI: It's more than a hint. You can't cast away the const_ness and use the object in a non-const way. That would be Undefined Behavior, and may break in quite unexpected ways. One _expected_ way in which it breaks is that the compiler may have created multiple copies of a constant, and you'd change only one. – MSalters Sep 04 '14 at 09:58
  • You do not have to initialize it in the constructor initializer list, e.g. `int count = 0;` in OP's code. – M.M Sep 04 '14 at 10:04
  • @ MSalters: IMO you are partially right, [it is 1 of 3 scenarios](http://stackoverflow.com/questions/7349559/undefined-behaviour-with-const-cast). So `const` is no guarantee that it will never be changed. – lifeOfPI Sep 04 '14 at 10:04
  • `lifeOfPi` a const object may not be modified by your code, end of story. – M.M Sep 04 '14 at 10:05