指向不完整类型的指针可以不完整吗?

Eri*_*hil 10 c pointers language-lawyer incomplete-type

可以int (*)[]是不完整的类型吗?

C 2018 6.2.5 1 说:

在翻译单元内的各个点,对象类型可能不完整(缺乏足够的信息来确定该类型对象的大小)或完整(具有足够的信息)。

因此,似乎如果类型的大小已知,则该类型是完整的。6.2.6.1 28 规定某些类型的指针必须具有相同的大小(指向void和字符的指针、指向兼容类型的指针、指向结构的指针和指向联合的指针),但指向其他类型的指针可能会有所不同。

在 C 实现中,所有指针或指向数组的所有指针int都具有相同的大小,则 的大小int (*)[]是已知的,因此它是完整的。在一个实现中,比如说,对大数组使用不同的指针,大小是未知的,所以它是不完整的。

正如MM 指出的那样,根据 6.7.2.1 3 中的约束,结构不得包含类型不完整的成员,最终的灵活数组成员除外。这表明具有相同大小的指针struct { int (*p)[]; }的实现必须接受,而具有不同大小的实现必须接受此类数组的大小必须诊断约束违规。(这反过来意味着这样的声明不是严格遵守 C 的一部分。)

Chr*_*phe 6

未知大小的数组是不完整的:

\n\n
\n

未知大小的数组类型是不完整类型。对于该类型的标识符,它是通过在稍后的声明中指定大小(具有内部或外部链接)来完成的。

\n
\n\n

然而,该类型int (*)[]并非不完整:它是一个int未知大小的数组的指针。
\n并且指针具有众所周知的大小:

\n\n
printf ("Size %d\\n", sizeof(int (*)[]));\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

6.2.5/23:如果类型不是不完整且不是可变长度数组类型,则该类型具有已知的常量大小。

\n
\n\n

此外,由于数组语义,您甚至可以取消引用它:

\n\n
typedef int (*T)[];\n...\nint a[10];\nfor (int i=0; i<10; i++) a[i]=i;\nT p=a;\nfor (int i=0; i<10; i++) printf ("%d ",(*p)[i]);\nprintf ("\\n");\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑

\n\n

此外,指针始终是完整类型。6.2.5/20 中是白底黑字:

\n\n
\n

指针类型可以派生自函数类型或对象类型,称为引用类型。指针类型描述一个对象,其值提供对所引用类型的实体的引用。从引用类型 T 派生的指针类型有时称为指向 T\xe2\x80\x99\xe2\x80\x99 的指针。从引用类型构造指针类型称为\xe2\x80\x98\xe2\x80\x98指针类型派生\xe2\x80\x99\xe2\x80\x99。指针类型是完整的对象类型。

\n
\n