Defining an array at the global scope using
const int DIM = 10;
int tab[DIM];
Is not allowed in C (but is supported in c++) because the array dimensions for objects defined at global scope (and local scope with global storage class specified by the static keyword) must be an integer constant expression. Integer constant expressions cannot be computed using the value of const variables as specified in the C Standard (before C23):
6.6 Constant expressions
Constraints
3 Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.
4 Each constant expression shall evaluate to a constant that is in the range of representable values for its type.
8 An integer constant expression shall have integer type and shall only have operands that are integer constants, named and compound literal constants of integer type, character constants, sizeof expressions whose results are integer constants, alignof expressions, and floating, named, or compound literal constants of arithmetic type that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the typeof operators, sizeof operator, or alignof operator.
Defining tab as a local array in the main function with automatic storage is allowed since C99 and creates a variable length array (VLA) whose length is computed at run time by evaluating the expression, and is constant for the life time of the object. Note however these limitations:
- the length must not be
0 (so the code in the question invokes undefined behavior if DIM is not initialized).
- if the length exceeds available stack space space at the point of definition, undefined behavior is invoked (and probably results in a stack overflow).
- such arrays cannot be initialized with an initializer.
There are other ways to express the array length with an identifier:
#define DIM 10
int tab[DIM];
or
enum { DIM = 10 };
int tab[DIM];
The latest version of the C Standard added the constexpr storage class which allows variables to be used in integer constant expressions. Recent compiler versions (gcc version 13 or clang version 19) with -std=c23, support this version:
constexpr int DIM = 10;
int tab[DIM];
constexpr int DIM = 10; int tab[DIM];is OK at global scope.