I just noticed that every modern OO programming language that I am at least somewhat familiar with (which is basically just Java, C# and D) allows covariant arrays. That is, a string array is an object array:
Object arr = new String; // Java, C# and D allow this
Covariant arrays are a hole in the static type system. They make type errors possible that cannot be detected at compile-time, so every write to an array must be checked at runtime:
arr = "hello"; // ok arr = new Object(); // ArrayStoreException
This seems like a terrible performance hit if I do lots of array stores. C++ does not have covariant arrays, so there is no need to do such a runtime check, which means there is no performance penalty.
Is there any analysis done to reduce the number of runtime checks necessary? For example, if I say:
arr = arr;
one could argue that the store cannot possibly fail. I'm sure there are lots of other possible optimizations I haven't thought of. Now, do modern compilers actually do these kinds of optimizations, or do I have to live with the fact that, for example, a Quicksort always does O(n log n) unnecessary runtime checks?
Are there other modern OO languages (besides the ones mentioned) that do not have covariant arrays?