2

I have been trying to use a const as the size of an array inside a class declaration. I know it works if I use a static const, but I am having trouble understanding why exactly. More specifically, why can I use const for some data members in a class, but must specify static const for others, as follows:

class Test
{
public:
   static const int size = 10;   // 1. Works. Must be static to use it as size of array
   const int alpha = 20; // 2. Works, but cannot use as size of an array
   const double beta = 10.0; // 3. Works
   static const double gamma = 20.0; // 4. does not compile

   int table[size];  // Works with size, but not alpha
};

I have read many explanations, but have not found an one (or at least one I understand) specifically for what makes case 1 different from case 4, and why I need to make the const static for the array.

Can anyone shed some light on this?

Edit: I'm using VS 2013 if that makes a difference

fschmeck
  • 21
  • 1
  • 1
    Size of arrays must be determined at time of compilation, therefore a static value must be used in the array declaration. – Sean Cox Nov 18 '15 at 03:09
  • Outside of a class using [a const int would work](http://stackoverflow.com/q/21273829/1708801) but in the class body it is not really const since you initialize it in the constructor so the value can change unlike `size`. – Shafik Yaghmour Nov 18 '15 at 03:11
  • Case 4 uses a `double`. Array sizes must be integers. A 2.5 element array would be a very interesting this to see, though. Like the average 2.5 child family. – user4581301 Nov 18 '15 at 03:17
  • Stupid comments aside, this is an interesting one. I don't know why `static const int` is valid but `static const double` isn't. Probably have to wait for a language lawyer to check in. – user4581301 Nov 18 '15 at 03:21
  • @Shafik that is the right answer, but he OP may need the explanation for why non static variables initialized that way are not actually const at compile time. – John Drouhard Nov 18 '15 at 03:25
  • `const int alpha` could conceivably have different values in different `Test` objects if alpha is set in the constructor. Eg `Test():alpha(42){}` so it can't be used as a size. – user4581301 Nov 18 '15 at 03:25
  • By the way, if the value is known at compile time, that’s what `constexpr` is for. – Davislor Nov 18 '15 at 03:45
  • @JohnDrouhard Shafik's answer does indeed help, along with the explanation from M.M below. I think I now have a better understanding why the int needs to be static, but why can't the double also be static? – fschmeck Nov 18 '15 at 06:46
  • @JohnDrouhard I would have answered if I could have tracked down the standard quote that said that, I know it is the case but I don't see where the standard says so which is annoying. – Shafik Yaghmour Nov 18 '15 at 10:23
  • We can find the double case covered in my answer to [Constant expression initializer for static class member of type double](http://stackoverflow.com/q/32813953/1708801). It may not be obvious to some since there used to a [gnu extension that allowed this](http://stackoverflow.com/q/32813953/1708801). – Shafik Yaghmour Nov 18 '15 at 10:23

3 Answers3

2

The difference is that:

const int alpha = 20;

is specifying that 20 is the default value which an object's alpha would get if you don't specify any other value. However the class could easily have a constructor that overrides this, e.g.:

// header file:
struct S
{
    S();
    S(int);
    const int alpha = 20;
};

// .cpp file
S::S(int): alpha(30) { }
S::S(): alpha(40) {}

So the value of alpha could in fact be different for different objects. This means that the size of the object cannot depend on it, because all objects of the same type must have the same size and layout.

However in the case static const int size = 10;, this specifies right then and there that size does have value 10 and nothing later on can supersede this; so this can be used as array sizes and so on. There is only a single size variable which is separate to any objects of the class.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • This is a great way of explaining why the int must be static! But why can't the double be static as well? – fschmeck Nov 18 '15 at 06:50
0

but have not found an one (or at least one I understand) specifically for what makes case 1 different from case 4,

An array size can only be an integral expression can be computed at compile time. Since gamma is of type double, you cannot use it as the size of an array.

why I need to make the const static for the array.

A non-static member exists only as a member of an object of the class. Its value is not usable without an object of the class. That throws up a catch-22 situation. You can't define the class without the size. You can't get the size without an object. A static member solves that problem.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
-1

C++ doesn't allow non-constant values for the size of an array. That's just the way it was designed. Array's size must be determined at compile time.

If you want a dynamically sized array, you need to allocate memory for it (and free it with delete when you're done).

Miguel Cunha
  • 663
  • 8
  • 16