I write this note because the 2014 Aug Wikipedia article describes a related idea that is different from what I remember. My detailed experience with dope vectors stems from IBM’s PL/I compilers of the early 70’s. I bet that they have not much changed.
As the compiler processes a program source there is some information about an array that it can discern and other information that is left flexible until the program runs. In general the dope vector holds just that data that is not known at compile time. The dope vector is produced by compiled code that runs as some generation of the array is created. The dope vector is consulted by compiled code that runs as the array is accessed. Access to the array is passed by passing the address of the dope vector. The compiler learns how many dimensions there are in an array at compile time but the index range for each of those dimensions is, by the definition of PL/I determined at run time. Also the virtual origin of the array is typically unknown at compile time and is thus included in the dope vector.
Sometimes the stride for each dimension is also included. The stride for the jth dimension is the cofactor of the jth index in the formula for calculating the offset from the virtual origin. Sometimes the stride is omitted and calculated as the product of the magintudes of the lesser ranges. The virtual origin is the address that the element b[0, 0, ..., 0] would have even if not all of the index ranges include 0.
Some languages can slice an array reference. Typically one can omit the entire index expression in the array reference and the result denotes a new array, sharing storage with the old, whose size is the range of the dimension whose index was omitted. That is calles a slice. In general k index expressions may be omitted which then denotes a k dimensional matrix. Compiled code produces a new dope vector from the original in this case.
Some languages go further and allow trimming wherein a syntactic reference to the array may for some index expressions give a pair of numbers, separated by a colon. This describes a new array, sharing storage with the old, but with a more limited range for that subscript. For such languages the dope vector must include each stride for those cannot be calculated from the index ranges alone. Again compiled code can produce a new dope vector from the old.
PL/I provided slicing and perhaps trimming. Algol 68 provides both.
This dope vector discipline allows a primitive function that given a dope vector for a 2D array, compute another dope vector for its transpose. I don’t know a language where such a function can be defined but a recent Algol68 compiler has included it as a primitive.
There is a design temptation to allow modifications to the array that let it shrink or even expand. Such actions would be incompatible with a caller of this routine who was in the midst of passing over the array. Upon resumption of that routine the registers that locate the current array element would be invalid.