Variables with variably modified type are only permitted at block scope (i.e. inside a function).
Variably modified type means an array type where one of the dimensions is not known at compile-time, or any type derived from that (e.g. pointer to such an array, as in your example).
int (*ptr)[n]
has variably modified type because n
is not a constant expression. For historical reasons, const int n = 4;
would not count as a constant expression either. But #define n 4
would be a constant expression.
One workaround is to write:
int (*ptr)[ sizeof array / sizeof array[0] ] = &array[0]; // note: no cast required
Background: Variably modified type was added in C99, to support arrays whose dimension are not known until runtime.
Although actually using such an array is risky due to stack overflow, this syntax enables some nice follow-on effects. For example, the ability to use array syntax with malloc'd arrays, and the ability to have a function which can operate on a multi-dimensional array using array syntax; but accept various sizes of array.
For rationale as to why they are not permitted at file scope, see the answers to this question. (Currently that question is incorrectly closed as duplicate, but the answers are good)