如果两个类型在C中彼此兼容,这到底是什么意思? [英] What does it mean exactly if two types are "compatible" to each other in C?
问题描述
在C标准中陈述(强调我的):
我从这些句子中得到的信息不多,也不是很有帮助。通常,引用的部分也不提供有关兼容的确切含义的更多信息。如果两个类型的类型相同,则它们具有兼容的类型。类型说明符的6.7.2、类型限定符的6.7.3和声明符的6.7.6中描述了确定两个类型是否兼容的其他规则。56)
56)两种类型不必完全相同即可兼容。
来源:C18,§6.2.7/1-兼容类型和复合类型
我现在知道,这两种类型如果具有相同的类型是兼容的,但如果它们不具有相同的类型/是相同的,也可以兼容。
我发现两个不完全相同的类型彼此兼容的一个地方是,如果我将一个类型与此原始类型的typedef
d类型或与原始类型的任何typedef
d类型进行比较,这两种类型都是兼容的,如§6.7.8/4和/5:
§6.7.8/4:
示例1之后
typedef int MILES, KLICKSP(); typedef struct {doublehi, lo; } range;
结构
MILES distance; extern KLICKSP *metricp; range x; range z,*zp;
都是有效声明。
distance
的类型是int
,metricp
的类型是指向函数的指针,没有参数说明返回的是int
和z
,x
和z
是指定的结构,zp
是指向这样的结构的指针。对象distance
具有与任何其他int
对象兼容的类型。
和
§6.7.8/5:
示例2声明后
typedef structs1 { int x; } t1, *tp1; typedef structs2 { int x; } t2, *tp2;
类型
t1
和tp1
指向的类型兼容。类型t1
也与类型structs1
兼容,但与tp2
指向的类型structs2
、t2
或int
不兼容。
但它仅显示了有关typedef
的一个示例,其中类型如果不相同,则可以兼容。
我的问题:
如果两种类型不完全相同,在什么(所有)情况下可以兼容?以及
兼容类型确切地说是什么?/如果两个类型相互兼容意味着什么?
什么规定了兼容性?
这就是我要找的,但直到现在才在标准中找到。
如果可能,请参阅答案中的标准部分。
其他研究:
我发现与范围、表示或行为相关的兼容性不是强制性的:
§6.2.5/15:
char
、signed char
和unsigned char
三种类型统称为字符类型。实现应将char
定义为具有与signed char
或unsigned char
相同的范围、表示和行为。45)<limits.h>
中定义的)CHAR_MIN
将具有值0
或SCHAR_MIN
之一,这可用于区分这两个选项。无论选择哪种类型,char
都是与其他两种类型不同的类型,与中的任何一种都不兼容。
引用第一句话中的部分:
引用的6.7.2、6.7.3和6.7.6节没有更多地解释什么是兼容类型,它们仅针对类型应该是兼容类型时的特定情况强制执行规则。
§6.7.2/4:
每个枚举类型应与char、带符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,131),但应能够表示枚举的所有成员的值。枚举类型直到紧跟在终止枚举数声明列表的}之后才是不完整的,并在其后完成。
§6.7.3/11:
要使两个限定类型兼容,这两个类型都应该具有兼容类型的相同限定版本;类型限定符在说明符或限定符列表中的顺序不影响指定的类型。
§6.7.6.1/2:
要使两个指针类型兼容,这两个指针类型应具有相同的限定符,并且都应是指向兼容类型的指针。
§6.7.6.2/6:
要使两个数组类型兼容,两个数组类型都应该具有兼容的元素类型,如果两个大小说明符都存在,并且都是整数常量表达式,则两个大小说明符应该具有相同的常量值。如果在要求两个数组类型兼容的上下文中使用这两个数组类型,则如果两个大小说明符的计算结果不相等,则是未定义的行为。
§6.7.6.3/15:
对于要兼容的两个函数类型,两者都应指定兼容的返回类型。149)此外,参数类型列表(如果两者都存在)应在参数数量和省略号终止符的使用上一致;相应的参数应具有兼容的类型。如果一种类型具有参数类型列表,而另一种类型是由不属于函数定义且包含空标识符列表的函数声明符指定的,则参数列表不应具有省略号终止符,并且每个参数的类型应与应用默认参数提升所产生的类型兼容。如果一种类型具有参数类型列表,而另一种类型是由包含(可能为空的)标识符列表的函数定义指定的,则两者应在参数数量上达成一致,并且每个原型参数的类型应与将默认参数提升应用于相应标识符的类型所产生的类型兼容。(在确定类型兼容性和复合类型时,使用函数或数组类型声明的每个参数被视为具有调整后的类型,使用限定类型声明的每个参数被视为具有其声明类型的非限定版本。)149)如果两个函数类型都是旧样式,则不比较参数类型。
相关:
Is a redeclaration of an untagged structure a compatible type?
Compatible types and ignoring top-level qualifiers in the C type system
推荐答案
它实际上来自于:
- 引用同一对象或函数的所有声明都应具有兼容的类型;否则,行为是未定义的。
因此,您可以看到,该标准允许在这里工作的任何东西都必然是兼容的。例如,类型int []
与int [10]
不同,但它们是兼容的,因为标准允许您声明
extern int foo[];
在一个文件中,并定义
int foo[10];
在另一个文件中,并使用外部标识符作为未知大小的数组访问foo
,因此这些类型是兼容的,但不完全相同。
C11/18 6.7.6.2p6中明确说明:
- 要使两个数组类型兼容,两个数组类型都应该具有兼容的元素类型,如果两个大小说明符都存在,并且都是整数常量表达式,则两个大小说明符应该具有相同的常量值。如果在要求两个数组类型兼容的上下文中使用这两个数组类型,则如果两个大小说明符的计算结果不相等,则是未定义的行为。
这篇关于如果两个类型在C中彼此兼容,这到底是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!