C standard defines a lot of lower/upper limits (translation limits) and imposes an implementation should satisfy for each translation. Why there's no such minimum limit defined for an array size? The following program is going to compile fine and likely produce runtime error/segfault and would invoke undefined behaviour.
int main()
{
int a[99999999];
int i;
for(i=0;i<99999999;i++)
a[i]=i;
return 0;
}
A possible reason could be local arrays are allocated on automatic storage and it depends on the size of the stack frame allocated. But why not a minimum limit like other limits defined by C?
Let's forget about the undefined cases like above. Consider the following:
int main()
{
int a[10];
int i;
for(i=0;i<10;i++)
a[i]=i;
return 0;
}
In the above, what gives me the guarantee that the local array (despite a very small one) is going to work as expected and won't cause undefined behaviour due to allocation failure?
Although it's unlikely that an allocation for such a small array would fail on any modern systems. But the C standard doesn't define any requirements to satisfy and compilers don't (at least GCC doesn't) report allocation failures. Only a runtime error/undefined behaviour is possibility. The hard part is nobody can tell whether an arbitrary sized array is going cause undefined behaviour due to allocation failure.
Note that I am aware I can use dynamic arrays (via malloc & friends) for this purpose and have a better control over allocation failures. I am more interested in why there's no such limit defined for local arrays. Also, global arrays are going to be stored in static storage and is going to increase executable size which compilers can handle.
The MINIMUM limit is an array of 1 element. Why would you have a "limit" for that? Of course, if you call a function recursively forever, an array of 1 may not fit on the stack, or the call that calls the function next call around may not fit on the stack - the only way to solve that would be to know the size of the stack in the compiler - but the compiler doesn't actually know at that stage how big the stack is - never mind the problems of extremely complex call hierarchies were several different functions call into the same function, possibly with recursion and/or several layers of rather large consumers of stack - how do you size the stack for that - the worst possible case may not be ever encountered, because other things dictate that this doesn't happen - for example, the worst case in one function is only when an input file is empty, but the worst case in another function is when there is lots of data stored in the same file. Lots and lots of variations like this. It's just too unreliable to determine, so sooner or later it would just become guess-work or of lots of false positives.
Consider a program with thousands of functions, all of which call the same logging function that needs a 200 byte array on the stack for temporarily storing the log output. It's called from just about every function from main upwards.
The MAXIMUM for a local variable depends on the size of the stack, which, like I said above, is not something the compiler knows when compiling your code [the linker MAY know, but that's later on]. For global arrays and those allocated on the heap, the limit is "how much memory your process can get", so there's no upper limit there.
There's just no easy way to determine this. And many of the limits provided by the standard is there to guarantee that code can be compiled on "any compiler" as long as your code follows the rules. Be compiled and be able to run to completion is two different things.
int main()
{
while(1);
}
will never run to completion - but it will compile in every compiler I know of, and most won't say a thing about there being an infinite loop - it's your choice to do that.
It's also your choice to put large arrays on the stack. And it could well be that the linker is given several gigabytes of stack, in which case it'll be fine - or the stack is 200K, and you can't have 50000 array of integers...
Because C, the language, should not be imposing limitations on your available stack size. C operates in many (many) different environments. How could it possibly come up with a reasonable number? Hell, automatic storage duration != stack, a stack is an implementation detail. C, the language, says nothing of a "stack".
The environment decides this stuff, and for good reason. What if a certain environment implements automatic storage duration via an alternative method which imposes no such limitation? What if a breakthrough in hardware occurs and all of a sudden modern machines do not require such a limitation?
Should we rev the standard in such an event? We would have to if C, the language, specified such implementation details.
You've already answered your own question; it's due to stack limitation.* Even this might not work:
void foo(void) {
int a;
...
}
if the ...
is actually a recursive call to foo
.
In other words, this is nothing to do with arrays, as the same problem affects all local variables. The standard couldn't enforce a requirement, because in practice that would translate into a requirement for an infinite-sized stack.
* Yes, I know the C standard(s) don't talk about stacks. But that's the implicit model, in the sense that the standard was really a formalisation of the implementations that existed at the time.