14

In the following code, const int cannot be used as an array size:

const int sz = 0;
typedef struct
{
   char s[sz];
} st;

int main()
{
   st obj;
   strcpy(obj.s, "hello world");
   printf("%s", obj.s);
   return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mahmoud Tmam
  • 143
  • 1
  • 1
  • 6

3 Answers3

19

This is because in C const actually means read only. Quoting C FAQ 1.18 and 1.19:

The const qualifier really means ``read-only''; an object so qualified is a run-time object which cannot (normally) be assigned to. The value of a const-qualified object is therefore not a constant expression in the full sense of the term, and cannot be used for array dimensions, case labels, and the like. (C is unlike C++ in this regard.) When you need a true compile-time constant, use a preprocessor #define (or perhaps an enum).

References: ISO Sec. 6.4 H&S Secs. 7.11.2,7.11.3 pp. 226-7

There are two ways of dealing with it:

  1. Use #define instead of const
  2. Use enum { sz = 12 };
syntagma
  • 23,346
  • 16
  • 78
  • 134
17

In C, a const-qualified variable is not a constant expression1. A constant expression is something that can be evaluated at compile time - a numeric literal like 10 or 3.14159, a string literal like "Hello", a sizeof expression, or some expression made up of the same like 10 + sizeof "Hello".

For array declarations at file scope (outside the body of any function) or as members of struct or union types, the array dimension must be a constant expression.

For auto arrays (arrays declared within the body of a function that are not static), you can use a variable or expression whose value isn't known until runtime, but only in C99 or later.


  1. C++ is different in this regard - in that language, a const-qualified variable does count as a constant expression.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 1
    It cannot be asserted without qualification that a `const`-qualified variable is not a *constant expression*. Although the C standard does not require a *constant expression* to include a `const`-qualified variable, C 2018 6.6 10 says “An implementation may accept other forms of constant expressions.” (And the same text is in C 1999.) – Eric Postpischil Oct 02 '18 at 13:50
  • C is also different from C++ in that `10` is not called a _numeric literal_, but an _integer constant_. Aside: C's _literals_, _string_ and _compound_, can have their addresses taken, unlike an integer constant. – chux - Reinstate Monica Oct 02 '18 at 14:48
5

In a very simple way because the compiler must know the dimension of the array at compilation time and since you can initialize const variable at run time you can't do it. So the size of statically declared arrays must be a constant expression and a const variable is not it. For constant expression you should use either a macro (#define) or enum. That's explicitly for your case (at file scope) and if you use a minimum standard of c99.

Jens
  • 69,818
  • 15
  • 125
  • 179
simo-r
  • 733
  • 1
  • 9
  • 13
  • Thanks, yes, this is the answer that got me thinking: "since you can initialize const variable at run time." Example: void f(int a) { const int size = a; int array[size] = { 0 }; } size is constant within scope of the function, but can be initialized to any value at runtime, so the array size is not determinable at compile-time. – Electo Nov 21 '22 at 21:12