如果两种类型在 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 相同,则它们也可以兼容。

我发现两个不同类型彼此兼容的一个地方是,如果我将一种类型与此原始类型的 typedefd 类型或任何 typedefd 类型进行比较对于原始类型,两种类型都是兼容的,如 §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 t1and 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.


相关:

其实来源于:

  1. 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中明确说明:

  1. 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 声明会导致不同但兼容的类型。