What was the reasoning behind not explicitly storing an array's length with an array in C?

The way I see it, there are overwhelming reasons to do so but not very many in support of the standard (C89). For instance:


Having length available in a buffer can prevent buffer overrun.
A Java-style arr.length is both clear and avoids the programmer from having to maintain many ints on the stack if dealing with several arrays
Function parameters become more cogent.


But perhaps the most motivating reason, in my opinion, is that usually, no space is saved without keeping the length. I would venture to say that most uses of arrays involve dynamic allocation. True, there may be some cases where people use an array allocated on the stack, but that's just one function call* - the stack can handle 4 or 8 bytes extra.

Since the heap manager has to track the free block size used up by the dynamically allocated array anyway, why not make that information usable (and add the additional rule, checked at compile time, that one can't manipulate the length explicitly unless one would like to shoot oneself in the foot).

The only thing I can think of on the other side is that no length tracking may have made compilers simpler, but not that much simpler.

*Technically, one could write some kind of recursive function with an array with automatic storage, and in this (very elaborate) case storing the length may indeed result in effectively more space usage.

C arrays do keep track of their length, as the array length is a static property:

int xs[42];  /* a 42-element array */


You can't usually query this length, but you don't need to because it's static anyway – just declare a macro XS_LENGTH for the length, and you're done.

The more important issue is that C arrays implicitly degrade into pointers, e.g. when passed to a function. This does make some sense, and allows for some nice low-level tricks, but it loses the information about the length of the array. So a better question would be why C was designed with this implicit degradation to pointers.

Another matter is that pointers need no storage except the memory address itself. C allows us to cast integers to pointers, pointers to other pointers, and to treat pointers as if they were arrays. While doing this, C is not insane enough to fabricate some array length into existence, but seems to trust in the Spiderman motto: with great power the programmer will hopefully fulfill the great responsibility of keeping track of lengths and overflows.
