Microsoft: "Rather than changing the run-time representation of a pointer in order to support bounds checking, in Checked C the programmer associates abounds expression with each_Array_ptr<T>-typed variable and member to indicate where the bounds are stored. The compiler inserts a run-time check that ensures that deferencing an_Array_ptr<T>is safe (the compiler may optimize away the runtime check if it can prove it always passes). Bounds expressions consist of non-modifying C expressions and can involve variables, parameters, and struct field members. For bounds on members, the bounds can refer only to other members declared in the same structure."
Me: No array descriptors are generated by the compiler. The programmer tells the compiler the size of the array as an expression, and that expression is evaluated at the point in the program where the relevant declaration appears.
The Microsoft syntax is very Microsoft. It involves many leading underscores and long keywords. What I proposed involved adding C++ "&" references, and making lengths explicit in the places in C where you can write "[]". This is more concise. The basic idea is the same, though. Arrays have a length, which is defined by some expression on nearby variables, such as other fields of the same struct or other parameters in the same function call. C programs that work usually have a length around somewhere, but the compiler doesn't know where it is. Make that explicit, and you can check.
If you add ranges and references to C syntax, and provide length information, you can deal with one of C's three big questions - "How big is it?" (The other two big questions are "who owns it?" and "what locks it?")
This area is 10% technology and 90% politics, so you need sizable organizational support to make much happen.
[1] http://www.animats.com/papers/languages/safearraysforc43.pdf