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[2]; // 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[0] = "hello"; // ok
arr[1] = 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[1] = arr[0];
one could argue that the store cannot possibly fail. I'm sure there are lots of other possible optimizations I haven't thought of.
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?
Can modern OO languages avoid the overhead created by supporting co-variant arrays?