c - 多维数组的别名

标签 c arrays multidimensional-array language-lawyer strict-aliasing

众所周知,二维数组是数组的数组,标准要求它是连续分配的非空对象集(6.2.5 类型§20)- 对象这里是一维数组。

众所周知,对于所有常见实现,以下等式对于 T arr2d[X][Y] 为真,其中 T 是类型,X 和 Y 是整数常量:

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

上面让我们认为它可以被允许为一个二维数组和一个相同大小的一维数组,或者甚至另一个总大小相同的二维数组起别名:

例如,下面的程序在没有警告的情况下编译和运行,并给出预期的输出:

#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('\n', stdout);
    }
    for (i=0; i<4; i++) {
        for (j=0; j<3; j++) {
            printf("%3d", arrx[i][j]); 
        }
        putc('\n', stdout);
    }
    return 0;
}

但是:

  • 第 (1) 和 (3) 行别名一个二维数组 3x4 到一个一维数组 12
  • 第 (2) 行别名一个 3x4 二维数组到 4x3 二维数组(通过指向 int 的指针)

我的问题是:

  • 根据 C 标准,(1) 和 (3) 是否有效?
  • 如果是,(2)是否有效?

最佳答案

即使严格的别名规则允许从包含它的对象访问一种类型的对象,标准中有两个元素表明不允许将二维数组别名到相同大小的一维数组:

兼容类型

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.

一致性:

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.

我的理解是,标准未指定二维数组与一维数组的别名,因此会导致未定义的行为。使用它的程序仍然是正确的程序,应该可以成功编译,但它的输出是未指定的

严格遵守程序不应将 2D 数组别名为 1D 数组。

话虽如此,通用实现允许它并按预期处理它(这是允许每个未定义的行为......)以便不破坏严重依赖它的遗留代码。

关于c - 多维数组的别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42951932/

相关文章:

c - 了解结构及其项目的声明位置

c - C 中的类型转换错误

php - 如何从关联数组中删除键及其值?

c# - 整数转换为字节后是什么样的?

我可以通过更好的数组操作来优化此代码吗?

c++ - Boyer Moore - 坏字符规则实现子串搜索

java - 为什么变量j的初始化不能在for循环的终止表达式中?

c - 正在做 c 作业并出现我不明白的错误

python - 在spark中创建一个多维随机矩阵

c - C 中 malloc 的内存泄漏问题