| RFC-0025:位标志 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 使用位标志声明扩展 FIDL 语言。 |
| 作者 | |
| 提交日期(年-月-日) | 2019-01-14 |
| 审核日期(年-月-日) | 2019-01-24 |
《Just a Little Bit》
摘要
使用位标志声明扩展 FIDL 语言。
设计初衷
在 FIDL 中,有多种使用情形需要通过整数来描述一组标志。目前,建议 FIDL 用户创建一组具有相同底层类型的常量。由于这些都是独立的,因此绑定在运行时无法检测到无效值的创建。
设计
源语言更改
此提案向 FIDL 添加了 bits 关键字。
bits 引入了顶级声明,类似于 enum。从形式上讲,语法中的产生式如下所示:
bits-declaration = ( attribute-list ) , "bits" , IDENTIFIER , ( ":" , type-constructor ) ,
"{" , ( bits-or-enum-member , ";" )+ , "}" ; [NOTE 1]
bits-or-enum-member = ( attribute-list ) , IDENTIFIER , ( "=" , bits-or-enum-member-value ) ;
bits-or-enum-member-value = IDENTIFIER | literal ; [NOTE 2]
注意:
bits-declaration允许语法中使用更宽松的type-constructor,但编译器将此限制为无符号整数类型,请参阅基元。bits-or-enum-member-value允许语法中出现更宽松的literal,但编译器将此限制为:enum上下文中的NUMERIC-LITERAL;NUMERIC-LITERAL,在bits的上下文中,必须是 2 的幂。
bits 声明中的每个成员都是 2 的幂。
为了简单起见,此提案建议不允许在 bits 声明本身中使用更复杂的表达式,也不允许在 bits 常量表达式中将它们与 OR 运算符组合使用。未来可能会添加到 bits 声明中。
以下示例展示了 bits 声明,该声明取自目前在 fuchsia.io 库中的常量:
bits OpenRights : uint32 {
READABLE = 0x00000001;
WRITABLE = 0x00000002;
ADMIN = 0x00000004;
};
此外,此提案还添加了二进制字面量语法,如下所示:
bits OpenRights : uint32 {
READABLE = 0b0001;
WRITABLE = 0b0010;
ADMIN = 0b0100;
};
语义
使底层整数类型溢出是一种编译错误。
每个 bits 成员值都必须是不同的。
序列化或反序列化设置了位(但该位不是 bits 声明的成员)的 bits 值时,会发生验证错误。
bits 的语义与 enum 不同。enum 值必须是 FIDL 中声明的某个值,而 bits 值则不一定。
例如,如果 OpenRights 为 enum,则唯一可发送的有效值为 1、2 和 4。不过,作为 bits 类型,0、3、5、6 和 7 也都是有效值。
绑定
每种语言绑定都将扩展为以惯用方式处理这些值。最坏的情况下,这只会为每个 bits 成员生成一个常量,就像它是底层类型的整数常量一样。
bits 值的有线格式与基础整数值相同。
序列化和反序列化代码应确保该值是所描述位数的子集。例如,尝试将 8 用作 OpenRights 值应会验证失败。
信号和权利常量
我还建议向 zx 库添加信号和句柄右值。
这包括对所有信号值和权限的 bits 声明,以及可能包含一组针对每种句柄类型的默认权限常量。
实施策略
第 1 阶段
将所有源代码更改添加到 FIDL 编译器,包括解析器测试。
第 2 阶段
为所有语言绑定和兼容性测试套件添加了支持。
第 3 阶段
将现有的整数常量堆迁移到 bits。
工效学设计
此变更让用户能够明确表达自己的意图,并让读者看到明确的分组,从而使 FIDL 更加符合人体工程学。
文档和示例
此提案描述了对上述 FIDL 语法所做的更改。
我会调整 FIDL 教程,以包含此模式的示例。
向后兼容性
这是对 FIDL 源的向后兼容性更改。
从有线格式来看,它是向后兼容的,因为无论以 uint32 还是 bits Bits :
uint32 的形式发送,(2 |
4) 或 6 的值在有线上都是相同的。
性能
将 FIDL 中的类型从 uint32 更改为 bits 值会在绑定中增加一些小开销,用于检查序列化或反序列化的值是否有效。
这是一个位掩码和分支,不太可能被注意到。
安全
我没有看到任何安全方面的缺点。 更好的类型安全性可能只是一个小小的优势。
测试
fidlc 主机单元测试将使用 FIDL 解析器。
兼容性测试套件将扩展为包含各种大小和值的 bits 类型,以测试所有受支持绑定的发送和接收路径。
缺点、替代方案和未知因素
此提案建议仅允许无符号整数类型的位。我认为可以允许有符号的基础类型,但需要在所有语言绑定中更加谨慎。我希望我们不要在 C/C++ 中意外地将位移得太远。
更通用的位字段模式似乎过于复杂,不值得在此提案中采用。 我的意思是,将一个整数类型划分为若干个位范围,并为每个位范围指定一个名称作为字段。
& 和 ~ 表达式感觉不必要,至少一开始是这样。
目标语言可以选择性地支持对位标志值进行此类算术运算,但我目前尚未看到直接在 FIDL 常量中使用此类运算的需求。
在先技术和参考资料
之所以不愿对成员值进行过于复杂的处理,并避免使用有符号类型,是因为 C 和 C++ 中这些概念一直令人困惑,而它们的绑定必须支持这一概念。