c-是一个不完整的枚举和一个完整的枚举兼容类型

  • 本文关键字:枚举 一个 类型 c enums
  • 更新时间 :
  • 英文 :


在一个翻译单元中,我有一个完全定义的枚举:

typedef enum E { A, B, C } ET;

在另一个例子中,我对这个枚举只有一个不完整的定义:

typedef enum E ET;

我想知道这两种类型是否兼容。

兼容类型的定义在本页中有描述,但对我来说似乎很模糊。当两个枚举是完整类型时,会有解释,但我不确定如果其中一个是而不是另一个,会发生什么。

下面的句子我应该理解什么?

一个是枚举类型,另一个是该枚举的底层类型

这是否意味着两种类型都兼容?

您的问题没有意义。C没有不完整的enum(与不完整的数组、并集或结构不同),即使当您不请求-pedantic一致性检查时,许多编译器都支持它们。

https://gcc.godbolt.org/z/vTv85v

没错,incomplete enum是一个类似于gcc不完整枚举的编译器扩展。答案的其余部分假设";incolpete enum";遵循与不完全结构和联合相同的规则。

不完整枚举和完整枚举兼容类型吗?

是(如果它们的名称相同)。

这是否意味着两种类型都兼容?

是。从您链接到的cppreference:

如果,类型T和U是兼容的

  • 它们是相同的类型(typedef引入的相同名称或别名)

Ie。ET是两个单元中enum E的别名——ET在两个单元都兼容。后来:

  • 它们都是结构/并集/枚举类型,并且
    • (C99)如果一个用标记声明,那么另一个也必须用相同的标记声明
    • 如果两者都是已完成类型,则blabla

在两个enum E中都有相同的标记-E,因此它们也是兼容的。第二个TU中的enum E是不完整的,因此附加点在此不适用。

让我们还提到C11 6.2.7的原始版本兼容类型和复合类型:

  1. 如果两个类型的类型相同,则它们具有兼容的类型
    6.7.2中对类型说明符、6.7.3中对类型限定符和6.7.6中对声明符描述了用于确定两个类型是否兼容的附加规则
    此外,如果在单独的翻译单元中声明的两个结构、并集或枚举类型的标记和成员满足以下要求,则它们是兼容的:如果其中一个用标记声明,则另一个应用相同的标记声明
    如果两者都在各自的翻译单位内的任何地方完成,则以下附加要求适用:
    它们的成员之间应该有一对一的对应关系,这样每对对应的成员都用兼容的类型声明
    如果用对齐说明符声明对中的一个成员,则用等效的对齐说明符声明另一个成员
    如果用名称声明对中的一个成员,则用相同的名称声明另一个成员
    对于两个结构,应按相同顺序声明相应的构件。对于两个结构或并集,相应的位字段应具有相同的宽度
    对于两个枚举,对应的成员应具有相同的值

下面的句子我应该理解什么?

一个是枚举类型,另一个是该枚举的底层类型

每个CCD_;底层类型"-它并不是真正的enum类型,它实际上是intchar或其他实现定义的类型。让我们引用C11 6.7.2.2枚举说明符:

  1. 每个枚举类型都应与char、带符号整数类型或无符号整数类型兼容。类型的选择由实现定义,但应能够表示枚举的所有成员的值。枚举类型在终止枚举器声明列表的}之后才是不完整的,然后才完成

第一句话相当明确。这个";实型";编译器的选择是依赖的——大多数时候它只是一个unsigned intint。请参阅编译器文档,如gcc实现定义行为4.9结构、并集、枚举和位字段:

与每个枚举类型兼容的整数类型(C90 6.5.2.2,C99和C11 6.7.2.2)。

通常,如果中没有负值,则类型为unsigned int枚举,否则为int。如果指定了-fshort enums,则如果有负值-它是有符号字符中的第一个,short和int,它可以表示所有值,否则它是unsigned char、unsigned short和unsigned int可以表示值。

在某些目标上,-fshort枚举是默认值;这是由ABI决定的。

这一点one is an enumerated type and the other is that enumeration's underlying type是关于unsigned intenum E可能是兼容的类型,所以您还不如使用unsigned int

此记录

typedef enum E ET;

不正确。

根据C标准(6.7.2.3标签)

3 形式的类型说明符

enum identifier
没有枚举器列表的

只能出现在它的类型之后指定已完成。

因此,如果前面有枚举E的完整声明,那么关于兼容性的问题就迎刃而解了。否则,编译器将发出错误消息。

最新更新