In C, const does not mean "constant" (that is, evaluated at compile time). It just means read only.
For example, inside a function, this is:
const int r = rand(); const time_t now = time(NULL);
excellent.
The name of an object defined as const int is not a constant expression. This means that (in C to C99 and in all versions of C ++) it cannot be used to determine the length of an array.
Although C99 (and, optionally, C11) support variable length arrays (VLAs), they cannot be initialized. Basically, the compiler does not know the size of the VLA when it is defined, so it cannot check if the initializer is valid. In your particular case, the compiler is most likely able to understand this, but the rules of the language are intended to cover a more general case.
C ++ is almost the same, but C ++ has a special rule that C does not have: if an object is defined as const , and its initialization is a constant expression, then the name of the object itself is a constant expression (at least for integral types) .
There is really no good reason that C did not use this function. In C, if you want an integer type name constant, the usual approach is to use a macro:
#define LEN 5 ... int arr[LEN] = {1, 2, 3, 4, 5};
Note that if you change the LEN value, you will have to overwrite the initializer.
Another approach is to use an anonymous enum :
enum { LEN = 5 }; ... int arr[LEN] = {1, 2, 3, 4, 5};
The name of the enumeration constant is actually a constant expression. In C, for historical reasons, it is always of type int ; in C ++, this is an enum type. Unfortunately, this trick only works for constants of type int , so it is limited to values ββranging from INT_MIN to INT_MAX .