RFC-0065:无可选字符串或矢量 | |
---|---|
状态 | 已拒绝 |
区域 |
|
说明 | 从 FIDL 语言中移除了可选字符串和可选矢量。 |
作者 | |
提交日期(年-月-日) | 2018-09-27 |
审核日期(年-月-日) | 2018-10-25 |
拒绝理由
- FTP-016 已被拒,即我们目前会保留可选字符串和矢量:
- 我们希望更全面地重新审视可选性,而不是做出单点决策。
- 自从我们开始思考这些功能的实用性以来,此功能的使用量有所增加,因此我们应该更好地了解现有模式,以及我们希望鼓励(和不鼓励)的模式。
- 在绑定级别:
- 改为不对非必需内容使用可选容器。我们应尽量简化处理非必需内容的流程,而不是简化处理可选内容的流程,也就是说,如果可选性适合该领域,您应明确寻求可选性。
- 关于 C++ 工效学:
StringPtr
->std::string
或fit::optional<std::string>
VectorPtr
->std::vector<T>
或fit::optional<std::vector<T>>
摘要
从 FIDL 语言中移除了可选字符串和可选矢量。
设计初衷
注意:在本文档中,我将使用“null 字符串”或“空矢量”一词。由于线路上的字符串本质上是必须是有效 UTF-8 的 vector<uint8>
,因此它们的线路格式非常相似,适用于其中一种格式的规则通常也适用于另一种格式。
在多种目标语言中,可为 null 的矢量和字符串难以表示且不符合人体工学,因此不广泛使用。虽然有些用例需要区分非字符串和空字符串,但我认为这样的用例很少,不值得强制这些位置明确表示这种情况。如果我们实现表格,这种情况可能会更加明显,因为表格可能会涵盖不存在的字符串或矢量的多个用例。
例如,在 C 和 C++ 中,null vector<T>
表示为长度为零且指向 null 的指针,而空 vector
表示为长度为零且指向非 null 的指针。根据语言规则,此非 null 指针必须是指向 T 的有效指针,即使它无法解引用也是如此。目前,我们构建此指针的方式是,假装次要对象存储空间的下一个位是 T 数组的最后一个位,这种做法在合法性方面充其量也只是可疑,而且在任何情况下都过于细微。我们修复了因这些规则的细微之处而导致的实现和客户端中的多个 bug。
此外,C++ 表示法在使用指向标准容器的指针来匹配标准矢量和字符串接口时,效率也不高。同样,Rust 必须将容器封装在 Option
中。
设计
此提案通过移除可选矢量和可选字符串结构来修改 FIDL 语言。
它会影响每个绑定的实现,因为无需为这些结构提供表示形式。
实施策略
- 废弃了 FIDL 语言中的这些结构体。
理想情况下,我们可以从
fidlc
发出废弃警告。 - 将
vector?
和string?
的所有用法迁移到其他表示法。 在某些情况下,相关接口实际上并不使用可选性。在其他情况下,我们可以手动说明可选性。 - 从 FIDL 以及示例和文档中移除了
vector?
和string?
。 - 对于每个目标语言:采用此提案现在允许的更好的字符串或矢量实现。例如,在 C++ 中,FIDL 矢量可以只是
std::vector
。
文档和示例
这些结构体有时会在 go/fidl-tut
等内容中引用,但从来没有以必不可少的方式引用。我们应将它们全部更新为非可选版本。
向后兼容性
这不允许在该语言中使用单个结构。旧版编译器将能够编译未来的代码。
由于我们尚未达到预期的源代码/编译器兼容性范围,因此成本很小。
性能
我预计性能不会有明显变化。
安全
我认为此功能对安全性没有影响。
测试
我们会逐个测试这些结构的用法,因此预计测试会一次进行 1 个 CQ。
我认为不需要为 fidl 流水线编写任何新测试。只需进行修改即可移除所有可选字符串或矢量。
缺点、替代方案和未知情况
我认为我们不应对生成的代码添加废弃警告。 最终,系统会引用更多这些代码,因此很难从后向追溯警告的真正来源。
在某些情况下,需要将非向量与空向量区分开来。不过,这同样适用于 uint32
,我认为在完成此提案和表格后,我们应该全面重新考虑可选性。
在先技术和参考文档
虽然其他 RPC 或 IPC 系统肯定也面临着此类问题,但我没有研究过任何一个。我认为在这种情况下,设计压力在与其他系统的兼容性、性能需求、目标语言支持等方面差异很大,因此我们不太可能仅通过查看其他系统是否支持可选字符串就得出有用的结论。