最近我在C代码中发现了以下数据结构定义:
typedef enum
{
Type1,
Type2,
Type3,
} TypesDefinition;
typedef struct {
Boolean variableA : 1;
Boolean variableB : 1;
Boolean variableC : 1;
Boolean variableD : 1;
TypesDefinition FailType : 4;
unsigned char newId;
unsigned char clientID : 8;
unsigned long int skip : 1;
unsigned long int unused2 : 7;
} DataStructureName;
令人惊讶的是,这段代码成功地通过了 gcc 编译,并且 pahole 工具没有在这个数据结构中发现任何漏洞。
我的问题:在位域定义中混合不同类型是否可以接受?
在位域定义中混合不同类型是否可以接受?
这取决于你的意思,但是是的,问题中提出的结构定义暂时可以接受。
这里发生了几件事,其中
可能的术语问题。 的每个
出现type identifier : width ;
结构类型定义中是“位字段”。 因此,每个数据类型只能有一种声明的数据类型。 但我认为您要问的是同一结构中具有不同声明数据类型的多个位字段,并且这没有固有的问题。
位字段可声明的特定(整数)类型部分依赖于实现,但它们至少包括
_Bool
、signed int
和 unsigned int
。 从 C24 开始,它们还包括位精确整数类型。 根据实现情况,可能允许其他整数类型。 因此确实有多种类型可供选择。
枚举类型是整数类型,因此它们属于实现可以(但不要求)支持作为位域的声明类型的类型。
从语义上讲,位域的声明类型严格与它的值如何解释以及它的宽度有关,而不是关于它的存储如何布局。 某些实现可能会在使用位域的结构布局方面行使自己的自由裁量权' 在布局决策中声明类型,但即使这样做,它们也会受到 C 要求的限制,即在底层存储单元足够大以允许的情况下,无论声明的数据类型如何,相邻位域都会打包到同一个位域中。
没有特别的理由认为,对给定结构中的位域使用不同声明类型的混合本身会引起 C 编译器的反感,也不会导致结构以任何类型进行布局。未使用的位。
位域:
注释
位字段的以下属性是实现定义的:
- 是否允许除 int、signed int、unsigned int、_Bool(C99 起) 和(可能无符号)_BitInt(N)(C23 起) 之外的类型
另请阅读解释部分,该部分更详细一些。
令人惊讶的是这段代码成功地通过了gcc编译并且 pahole 工具在这个数据结构中没有发现任何漏洞。
bool
和枚举具有底层整数类型。