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


9

可以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的一部分。)


6.2.5(p22)帮助?(或者它增加了更多的混乱,使得不完整的类型可以在以后的声明中完成吗?)
David C. Rankin

@ DavidC.Rankin在6.2.5 / 20中,甚至有人说指针总是完整的类型
Christophe

@LanguageLawyer:那有什么关系?问题是“是否存在不是Y的X?”,而不是“是否存在X是Y?”
埃里克·波斯特皮希尔

@LanguageLawyer:void *完整的事实表明指向不完整类型的指针可以完整。它不显示指向不完整类型的指针是否可以不完整。如果有人问“哺乳动物可以成为大象吗?”,如果表明“狮子是哺乳动物”,就不能说明哺乳动物不能成为大象。该问题询问指向不完整类型的指针的集合X是否可能包含不完整的元素。指示不完整类型的指针集X包含一个完成元素是无关紧要的。
埃里克·波斯特皮希尔

@EricPostpischil糟糕!我将标题误读为“指向不完整类型的指针可以完整吗?”
语言律师

Answers:


3

未知大小的数组不完整:

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

但是类型int (*)[]不是不完整的:它是int大小未知的数组的指针。
指针的大小众所周知:

printf ("Size %d\n", sizeof(int (*)[]));

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

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

typedef int (*T)[];
...
int a[10];
for (int i=0; i<10; i++) a[i]=i;
T p=a;
for (int i=0; i<10; i++) printf ("%d ",(*p)[i]);
printf ("\n");

编辑

另外,指针始终是完整类型。它在6.2.5 / 20中写为黑底白字:

指针类型可以从称为引用类型的函数类型或对象类型派生。指针类型描述了一个对象,该对象的值提供对所引用类型的实体的引用。从引用的类型T派生的指针类型有时称为``T的指针''。从引用类型构造指针类型的过程称为“指针类型派生”。指针类型是完整的对象类型。


我认为您已将其归结为gcc同意。带指针的结构不完整的数组类似于提示讨论的原始问题。
David C. Rankin

仅最后一段是相关的。该示例printf仅显示了指向不完整数组的指针在问题中已执行的实现中是完整的,如问题中所述–如果不是最后一段中引用的6.2.5 20,则可能无法编译。6.2.5 23也无关紧要;它告诉我们尺寸是已知的,如果尺寸完整则为常数,并且我们已经知道尺寸完整就意味着尺寸是已知的。
埃里克·波斯特皮希尔

6.2.5 20很有趣。我推测这并不是要产生这种结果,但这意味着所有指向不完整的类型的指针在不完整时必须具有相同的大小。例如,指向的数组的所有指针int必须彼此具有相同的大小,并且指向某个数组的所有指针struct必须彼此具有相同的大小,尽管并非所有指向不同类型的数组的指针都struct必须具有相同的大小。彼此。
埃里克·波斯特皮希尔

1
@EricPostpischil可能是文本“类似地,指向兼容类型的合格或不合格版本的指针应具有相同的表示和对齐要求。” 应该被解释为T(*)[]必须与大小相同T(*)[5],因为它们是兼容类型,我们可以添加或删除限定符
MM

允许兼容类型具有不同的大小会导致很多问题,这可能是该标准未明确排除的缺陷
MM
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.