For the following code:
foo(int n){
int array[n];
}
I understand that this is invalid syntax and that it is invalid because the c++ sta
This is because the C++ language does not have the C feature introduced in C99 known as "variable length arrays" (VLA).
C++ is lagging in adopting this C feature because the std::vector
type from its library fulfills most of the requirements.
Furthermore, the 2011 standard of C backpedaled and made VLA's an optional feature.
VLA's, in a nutshell, allow you to use a run-time value to determine the size of a local array that is allocated in automatic storage:
int func(int variable)
{
long array[variable]; // VLA feature
// loop over array
for (size_t i = 0; i < sizeof array / sizeof array[0]; i++) {
// the above sizeof is also a VLA feature: it yields the dynamic
// size of the array, and so is not a compile-time constant,
// unlike other uses of sizeof!
}
}
VLA's existed in the GNU C dialect long before C99. In dialects of C without VLA's, array dimensions in a declaration must be constant expressions.
Even in dialects of C with VLA's, only certain arrays can be VLA's. For instance static arrays cannot be, and neither can dynamic arrays (for instance arrays inside a structure, even if instances of that structure are allocated dynamically).
In any case, since you're coding in C++, this is moot!
Note that storage allocated with operator new
are not the VLA feature. This is a special C++ syntax for dynamic allocation, which returns a pointer type, as you know:
int *p = new int[variable];
Unlike a VLA's, this object will persist until it is explicitly destroyed with delete []
, and can be returned from the surrounding scope.
Because it has different semantics:
If n
is a compile-time constant (unlike in your example):
int array[n]; //valid iff n is compile-time constant, space known at compile-time
But consider when n
is a runtime value:
int array[n]; //Cannot have a static array with a runtime value in C++
int * array = new int[n]; //This works because it happens at run-time,
// not at compile-time! Different semantics, similar syntax.
In C99 you can have a runtime n
for an array and space will be made in the stack at runtime.
There are some proposals for similar extensions in C++, but none of them is into the standard yet.
The one and only valid answer to your question is, because the standard says so.
In contrast to C99, C++ never bothered to specify variable length arrays (VLAs), so the only way to get variably sized arrays is using dynamic allocation, with malloc
, new
or some other memory-manager.
In fairness to C++, having runtime-sized stack-allocations slightly complicates stack-unwinding, which would also make exception-handling for the functions using the feature consequently more bothersome.
Anyway, even if your compiler provides that C99-feature as an extension, it's a good idea to always keep a really tight rein on your stack-usage:
There is no way to recover from blowing the stack-limit, and the error-case is simply left Undefined Behavior for a reason.
The easiest way to simulate VLAs in C++, though without the performance-benefit of avoiding dynamic allocation (and the danger of blowing the limit):
unique_ptr<T[]> array{new T[n]};