Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
708 views
in Technique[技术] by (71.8m points)

c - Aliasing of multi-dimensional arrays

It is well known that a 2D array is an array of arrays, and that it is required by standard to be a contiguously allocated nonempty set of objects (6.2.5 Types §20) - object being a 1D array here.

It is also well known that for all common implementations the following equality is true for T arr2d[X][Y] where T is a type and X and Y integral constants:

(char *) &arr2d[i][j] == (char *) &arr2d[0][0] + i * Y * sizeof(T) + j * sizeof(T)

The above let think that it could be allowed to alias a 2D array and an 1D array of same size, or even another 2D array of same total size:

For example the following program compiles and runs with no warnings, and gives expected output:

#include <stdio.h>

int main() {
    int i, j, k=0;
    int arr2d[3][4];   // array of 3 array of 4 ints
    int *arr1 = &arr2d[0][0];  // pointer to first element of an array of 12 ints (1)
    int (*arrx)[3] = (int(*)[3]) arr1; //pointer to first row of an array of arrays of 3 ints
                                       //(2)

    for (i=0; i<12; i++) arr1[i] = k++; // (3)

    for (i=0; i<3; i++) {
        for (j=0; j<4; j++) {
            printf("%3d", arr2d[i][j]);
        }
        putc('
', stdout);
    }
    for (i=0; i<4; i++) {
        for (j=0; j<3; j++) {
            printf("%3d", arrx[i][j]); 
        }
        putc('
', stdout);
    }
    return 0;
}

But:

  • line (1) and (3) alias a 2D array 3x4 to a 1D array 12
  • line (2) alias a 2D array 3x4 to a 2D array 4x3 (via a pointer to int)

My questions are:

  • are (1) and (3) valid according to the C standard?
  • if yes, is (2) valid?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Even if the strict aliasing rules allows to access an object of one type from an object containing it, there are two elements in standards to say that aliasing a 2D array to a 1D array of same size is not allowed:

Compatible type

6.2.7 Compatible type and composite type

1 Two types have compatible type if their types are the same.
...
3 A composite type can be constructed from two types that are compatible; it is a type that is compatible with both of the two types and satisfies the following conditions:

  • If one type is an array of known constant size, the composite type is an array of that size; otherwise, if one type is a variable length array, the composite type is that type.
    ...

These rules apply recursively to the types from which the two types are derived.

Conformance:

4 Conformance

...

  1. ... Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.
  2. A program that is correct in all other aspects, operating on correct data, containing unspecified behavior shall be a correct program and act in accordance with 5.1.2.3.
    ...
  3. A strictly conforming program shall use only those features of the language and library specified in this International Standard.2) It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.

My understanding is that aliasing of 2D array with a 1D array is unspecified by the standard and as such leads to undefined behaviour. A program using it is still a correct program that shall be successfuly compiled, but its output is unspecified

A stricly conforming program should not alias a 2D array to an 1D array.

That being said, common implementation allows it and process it as expected (which is allowed per undefined behaviour...) in order to not break legacy code that heavily depends on it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...