RFC-0051:更安全的 C++ 結構

RFC-0051:C++ 適用的更安全的結構
狀態已遭拒
領域
  • FIDL
說明

允許 C++ 開發人員編寫在編譯期間失敗的 FIDL 程式碼 (如果結構體未完整初始化)。

作者
提交日期 (年-月-日)2018-07-19
審查日期 (年-月-日)2019-03-14

拒絕原因

自 2019 年 3 月 14 日起,此 RFC 最初已獲接受。不過, implementation 從未合併,且 C++ 繫結 在那之後發生了重大變化意識到這一點,我們會溯及既往 拒絕這個 RFC。

摘要

允許 C++ 開發人員編寫會在編譯時中斷的 FIDL 程式碼 當結構體尚未完全初始化時,則會增加時間。

提振精神

Peridot 中的複雜 FIDL 結構體會隨著我們改善 瞭解如何解決所面臨的問題。 結構體通常很深層的巢狀結構,並以遠距離的方式傳送至程式碼 建構應用程式本身 疊代結構時,我們通常會對語意進行破壞性變更 添加必填欄位或將之前的選填欄位設為必填。 難以追蹤所有需要更新的程式碼。 這些錯誤不會顯示為編譯時間錯誤,而是執行階段錯誤, 難以關聯的初始化程式碼錯誤 來建構

Dart 程式碼在變更前都常出現相同的問題類別 需要將所有必填欄位傳遞至結構體 建構函式中設定。 這項變更讓開發 Dart 程式碼的開發效率和穩定性大幅提升。

設計

這會修改 C++ 繫結程式庫和程式碼產生器。 它不會移除任何現有介面,而只是新增 FIDL 結構體的執行個體。

這項操作會新增 FIDL 結構的建構工具模式。 使用方式如下:

FooPtr foo = Foo::Builder()->set_bar("hello")->set_baz("world");

結構類別上的 Builder() 靜態方法會傳回範本建構工具 物件。 建構工具範本參數會擷取正在建構的結構類型, 類別。 其保存了結構體的一個執行個體。

欄位類別有兩種方法:可設定值的 set_name(value) 方法 欄位值並傳回建構工具,並將該欄位從中移除 建構工具的範本引數,以及 Check() 方法 (非人工管理) 選填欄位,且必填欄位出現 static_assert 失敗。

建構工具類別會擴充其範本中的所有欄位類型 參數,以便開發人員存取 setter 方法。 當開發人員呼叫 setter 並接收新的建構工具類型清單時 建構工具範本引數中的欄位類別縮減 例如,隱藏部分範本資料:

Foo::Builder()Builder<Foo, Foo::Field_bar, Foo::Field_baz> 結合了 set_bar()set_baz() 方法。

Foo::Builder()->set_bar(...)Builder<Foo, Foo::Field_baz> 利用 set_baz() 方法建構程式碼

Foo::Builder()->set_bar(...)->set_baz(...)Builder<Foo> 不必使用任何 setter 方法

建構工具針對結構體類型使用隱含的轉換運算子 struct 指標型別。 這些方法會對其餘欄位類型呼叫 Check() 方法,並傳回 建構工具保留的結構執行個體 Check() 方法為免人工管理 (適用於選填欄位) 或 static_assert 失敗,可指定未設定必填欄位。

說明文件和範例

更新 FIDL 教學課程和範例,以呈現 是建立結構體例項的傳統和新方法。

回溯相容性

本提案僅供參考, 也不會產生回溯不相容的問題。

成效

這項變更不會產生執行階段效能費用。 之前是在編譯器多層檢視的原型 確保系統不會產生其他程式碼 執行狀態

這個檔案會在繫結程式庫中新增標頭檔案,並在郵件中另外新增幾個 。 C++ 編譯器必須執行一些額外工作來解析範本 但不會增加編譯的其他步驟 可能會產生重大影響

安全性

這項變更讓我們得以從執行階段錯誤中轉化程式設計師錯誤 導致建構時間錯誤 這樣可以減少程式的狀態空間,並減少錯誤數量 這些案例。 減少非預期行為能維護安全。

測試

您應擴充 C++ 繫結單元測試,以測試該建構工具 正確設定不同的欄位類型

要測試是否正確使用建構工具 (即 無法設定必填欄位) 會遭到編譯器擷取。 我們不清楚該如何測試。

缺點、替代方案和未知

這會為 FIDL C++ 繫結程式庫新增一些較為複雜的範本。 這會帶來維護負擔 建構時間負擔

先前的範本方法使用位元遮罩,但範本較為簡單 但設有 64 個必要欄位和 64 個必要欄位等限制 FIDL 編譯器

我們也可以建構 Linter,試著追蹤必填欄位 一切都設定妥當 這份資料流分析工作似乎相當複雜。

既有藝術品和參考資料

Dart 繫結去年有所變更,因此結構建構函式可以採用 每個欄位的具名引數 必要的設定檔會標示為必要項目,讓物件分析器能夠拒絕 造成部分欄位未初始化的變更。