不完整的数组类型是否与完整的数组类型兼容?

Is an incomplete array type compatible with a complete array type?

问题:int (*)[]int (*)[1] 兼容吗?

演示 1:

typedef int T0;
typedef T0  T1[];
typedef T1* T2[];

T1 x1 = { 13 };
T2 x2 = { &x1 };

GCC、Clang、ICC 不生成诊断信息。

MSVC 生成:

<source>(21): warning C4048: different array subscripts: 'T1 (*)' and 'T0 (*)[1]'

注意:T1 (*)int (*)[]T0 (*)[1]int (*)[1]

演示 2:

int c[][1] = {0};
int (*r)[] = c;

GCC、Clang、ICC 不生成诊断信息。

MSVC 生成:

<source>(30): warning C4048: different array subscripts: 'int (*)[0]' and 'int (*)[1]'

额外:C2x,6.7.6.2 数组声明符,6:

For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value. If the two array types are used in a context which requires them to be compatible, it is undefined behavior if the two size specifiers evaluate to unequal values.

Are int (*)[] and int (*)[1] compatible?

好像是的

C2x, 6.2.7兼容类型和复合类型, 5:

EXAMPLE Given the following two file scope declarations:

int f(int (*)(), double (*)[3]);
int f(int (*)(char *), double (*)[]);

The resulting composite type for the function is:

int f(int (*)(char *), double (*)[3]);

和:

A composite type can be constructed from two types that are compatible; ...

这里我们看到 double (*)[3] 是由类型 double (*)[3]double (*)[].

构造的复合类型

因此,类型 double (*)[3]double (*)[] 是兼容的。

因此,类型 int (*)[]int (*)[1] 是兼容的。

我认为您想通过添加标识符和类型定义来使事情​​复杂化。

typedef int T0;

T0 等同于 int 所以让我们简化并使用 int.

typedef T0 T1[]; ===>  int (T1[]); ===> int T1[];

这里,T1相当于一个未指定的数组类型,所以我们简化一下,用int [].

typedef T1* T2[]; ===> int (*T2[])[];

这是一个指向整数数组的指针数组

这里,T2相当于一个未指定的数组类型,所以我们简化一下,使用int (*[])[]

当你写作时

T1 x1 = { 13 }; ===>  int x1[] = { 13 }; ===> int x1[1] = { 13 };

因为类型最终由初始化器完全指定,它分配一个元素的数组长度。

T2 x2 = { &x1 }; ===> int (*x2[])[] = { &x1 };

其中 x1int *[1] 类型(因此 &x1int **[1] 类型。这将固定内部数组维度:

... ===> int (*x2[1])[];

并且,由于只有一个初始化程序,这也将修复外部数组维度:

... ===> int (*x2[1])[1];

所以最后 x2 导致一个指针数组指向一个 int 数组。

我建议您通过仅使用一种不完整类型而不是三层类型来简化您的示例,以便自己理解不完整的类型定义。这样你就可以在没有帮助的情况下解决问题。