11

从第6.2.7.5 节(第 66 页)开始:

示例给定以下两个文件范围声明:

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

函数的结果复合类型是:

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

在上面的例子中,他们解释了复合类型是一种类型,兼容两种不同的类型。我会直观地将“复合类型”这个短语理解为“结构和联合”的意思,这似乎是偏离目标的。

什么是 C 中的复合类型,它的用途是什么?有人可以详细解释上面的例子吗?

4

2 回答 2

9

我可能不是回答这个问题的合适人选,但对于它的价值,这里是 C99 的基本原理,它可能会有所帮助:

6.2.7 兼容型和复合型

引入兼容类型和复合类型的概念是为了允许 C89 讨论类型声明不需要相同的情况。这些术语在解释不完整类型和完整类型之间的关系时特别有用。通过在 C99 中添加可变长度数组(第 6.7.5.2 节),扩展了数组类型兼容性,以便可变长度数组与已知常量大小的数组和具有不完整类型的数组兼容。

两个不同翻译单元中的结构、联合或枚举类型声明不会正式声明相同的类型,即使这些声明的文本来自同一个头文件,因为翻译单元本身是不相交的。因此,该标准为这些类型指定了额外的兼容性规则,以便两个这样的声明在它们足够相似的情况下是兼容的。

C99 的安静变化

不同翻译单元中的结构或联合类型声明现在必须具有相同的标签才能兼容。

于 2013-05-07T11:53:08.730 回答
5

我会直观地将“复合类型”这个短语理解为“结构和联合”的意思,这似乎是偏离目标的。

在 C 语言定义中,数组和结构是聚合类型(由多个元素组成的类型)。联合是一种自己的动物,因为它们一次只能获取一个元素的值。

复合类型对于编译器实现者来说更多是一个问题,而不是我们普通的代码猴子。你我都不会尝试定义复合类型,或声明该类型的对象。

在给出的示例中,您有两个函数的文件范围声明,f它们彼此略有不同。根据 6.2.7/3 中提出的规则,编译器确定对两者都适用的类型,以便它可以在编译时强制执行类型语义(即,f可以正确检查任何调用,即使声明略有不同)并生成正确的机器代码来调用该函数。

于 2013-05-07T16:30:21.150 回答