如果两种类型在 C 中彼此 "compatible" 究竟意味着什么?
What does it mean exactly if two types are "compatible" to each other in C?
在C标准中规定(强调我的):
Two types have compatible type if their types are the same. Additional rules for determining whether two types are compatible are described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.6 for declarators. 56)
56)Two types need not be identical to be compatible.
Source: C18, §6.2.7/1 - "Compatible type and composite type"
我从这些句子中得到的信息不多,也不是很有帮助。所引用的部分通常也没有提供有关“compatible”确切 is/means.
的进一步信息
我现在知道,如果两种类型具有相同的类型,则它们是兼容的,但如果它们不具有相同的 type/be 相同,则它们也可以兼容。
我发现两个不同类型彼此兼容的一个地方是,如果我将一种类型与此原始类型的 typedef
d 类型或任何 typedef
d 类型进行比较对于原始类型,两种类型都是兼容的,如 §6.7.8/4 和 /5:
的示例中所述
§6.7.8/4:
EXAMPLE 1 After
typedef int MILES, KLICKSP();
typedef struct {doublehi, lo; } range;
the constructions
MILES distance;
extern KLICKSP *metricp;
range x;
range z,*zp;
are all valid declarations. The type of distance
is int
, that of metricp
is "pointer to function with no parameter specification returning int
", and that of x
and z
is the specified structure; zp
is a pointer to such a structure. The object distance
has a type compatible with any other int
object.
和
§6.7.8/5:
EXAMPLE 2 After the declarations
typedef structs1 { int x; } t1, *tp1;
typedef structs2 { int x; } t2, *tp2;
type t1
and the type pointed to by tp1
are compatible. Type t1
is also compatible with type structs1
, but not compatible with the types structs2
, t2
, the type pointed to by tp2
, or int
.
但它只显示了一个关于 typedef
的示例,其中类型可以 兼容 如果不相同。
我的问题:
在哪种(所有)情况下两种类型可以 兼容 如果它们不完全相同? , 和
什么是“兼容类型”? / 如果两种类型 兼容 是什么意思?
什么指定了“兼容性”?
这就是我要找的东西,直到现在还没有在标准中找到。
如果可能,请参考答案中标准部分。
进一步研究:
我发现与范围、表示或行为相关的兼容性不是强制性的:
§6.2.5/15:
The three types char
, signed char
, and unsigned char
are collectively called the character types. The implementation shall define char
to have the same range, representation, and behavior as either signed char
or unsigned char
.45)
45)CHAR_MIN
, defined in <limits.h>
, will have one of the values 0
or SCHAR_MIN
, and this can be used to distinguish the two options. Irrespective of the choice made, char
is a separate type from the other two and is not compatible with either.
引用第一条引文的部分:
引用的第 6.7.2、6.7.3 和 6.7.6 节没有更多地解释什么是 兼容类型,它们只针对特定情况规定了类型应遵循的规则是 兼容类型。
§6.7.2/4:
Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, 131) but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.
§6.7.3/11:
For two qualified types to be compatible, both shall have the identically qualified version of a compatible type; the order of type qualifiers within a list of specifiers or qualifiers does not affect the specified type.
§6.7.6.1/2:
For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.
§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.
§6.7.6.3/15:
For two function types to be compatible, both shall specify compatible return types.149) Moreover,the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types. If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list,both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)
149)If both function types are "old style", parameter types are not compared.
相关:
Compatible types and structures in C
Compatible types and argument type qualifiers
compatible types vs. strict aliasing rules
Are these compatible function types in C?
其实来源于:
- All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.
因此您可以看出,标准允许在这里工作的任何东西都必然是兼容的。例如类型 int []
不同于 int [10]
但它们是兼容的,因为标准允许您声明
extern int foo[];
在一个文件中定义
int foo[10];
在另一个文件中,并使用外部标识符作为未知大小的数组访问 foo
- 因此这些类型兼容,但不相同。
在C11/18 6.7.6.2p6中明确说明:
- 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.
非常感谢您的提问!我在试图揭示“如果类型相同,则两种类型具有兼容类型”这句话背后的含义时遇到了它。你帮助我意识到它只说明了两种类型兼容的 充分 条件。
在我看来,兼容性关系中最重要的属性是它克服了struct/union标签或typedef名称的范围。特别是,C17 直接指出 (§6.7.2.3/5):
Two declarations of structure, union, or enumerated types which are in
different scopes or use different tags declare distinct types.
也就是说,在两个或多个文件中使用相同的 struct/union 声明会导致不同但兼容的类型。
在C标准中规定(强调我的):
Two types have compatible type if their types are the same. Additional rules for determining whether two types are compatible are described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.6 for declarators. 56)
56)Two types need not be identical to be compatible.
Source: C18, §6.2.7/1 - "Compatible type and composite type"
我从这些句子中得到的信息不多,也不是很有帮助。所引用的部分通常也没有提供有关“compatible”确切 is/means.
的进一步信息我现在知道,如果两种类型具有相同的类型,则它们是兼容的,但如果它们不具有相同的 type/be 相同,则它们也可以兼容。
我发现两个不同类型彼此兼容的一个地方是,如果我将一种类型与此原始类型的 typedef
d 类型或任何 typedef
d 类型进行比较对于原始类型,两种类型都是兼容的,如 §6.7.8/4 和 /5:
§6.7.8/4:
EXAMPLE 1 After
typedef int MILES, KLICKSP(); typedef struct {doublehi, lo; } range;
the constructions
MILES distance; extern KLICKSP *metricp; range x; range z,*zp;
are all valid declarations. The type of
distance
isint
, that ofmetricp
is "pointer to function with no parameter specification returningint
", and that ofx
andz
is the specified structure;zp
is a pointer to such a structure. The objectdistance
has a type compatible with any otherint
object.
和
§6.7.8/5:
EXAMPLE 2 After the declarations
typedef structs1 { int x; } t1, *tp1; typedef structs2 { int x; } t2, *tp2;
type
t1
and the type pointed to bytp1
are compatible. Typet1
is also compatible with typestructs1
, but not compatible with the typesstructs2
,t2
, the type pointed to bytp2
, orint
.
但它只显示了一个关于 typedef
的示例,其中类型可以 兼容 如果不相同。
我的问题:
在哪种(所有)情况下两种类型可以 兼容 如果它们不完全相同? , 和
什么是“兼容类型”? / 如果两种类型 兼容 是什么意思?
什么指定了“兼容性”?
这就是我要找的东西,直到现在还没有在标准中找到。
如果可能,请参考答案中标准部分。
进一步研究:
我发现与范围、表示或行为相关的兼容性不是强制性的:
§6.2.5/15:
The three types
char
,signed char
, andunsigned char
are collectively called the character types. The implementation shall definechar
to have the same range, representation, and behavior as eithersigned char
orunsigned char
.45)45)
CHAR_MIN
, defined in<limits.h>
, will have one of the values0
orSCHAR_MIN
, and this can be used to distinguish the two options. Irrespective of the choice made,char
is a separate type from the other two and is not compatible with either.
引用第一条引文的部分:
引用的第 6.7.2、6.7.3 和 6.7.6 节没有更多地解释什么是 兼容类型,它们只针对特定情况规定了类型应遵循的规则是 兼容类型。
§6.7.2/4:
Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, 131) but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.
§6.7.3/11:
For two qualified types to be compatible, both shall have the identically qualified version of a compatible type; the order of type qualifiers within a list of specifiers or qualifiers does not affect the specified type.
§6.7.6.1/2:
For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.
§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.
§6.7.6.3/15:
For two function types to be compatible, both shall specify compatible return types.149) Moreover,the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types. If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list,both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)
149)If both function types are "old style", parameter types are not compared.
相关:
Compatible types and structures in C
Compatible types and argument type qualifiers
compatible types vs. strict aliasing rules
Are these compatible function types in C?
其实来源于:
- All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.
因此您可以看出,标准允许在这里工作的任何东西都必然是兼容的。例如类型 int []
不同于 int [10]
但它们是兼容的,因为标准允许您声明
extern int foo[];
在一个文件中定义
int foo[10];
在另一个文件中,并使用外部标识符作为未知大小的数组访问 foo
- 因此这些类型兼容,但不相同。
在C11/18 6.7.6.2p6中明确说明:
- 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.
非常感谢您的提问!我在试图揭示“如果类型相同,则两种类型具有兼容类型”这句话背后的含义时遇到了它。你帮助我意识到它只说明了两种类型兼容的 充分 条件。
在我看来,兼容性关系中最重要的属性是它克服了struct/union标签或typedef名称的范围。特别是,C17 直接指出 (§6.7.2.3/5):
Two declarations of structure, union, or enumerated types which are in different scopes or use different tags declare distinct types.
也就是说,在两个或多个文件中使用相同的 struct/union 声明会导致不同但兼容的类型。