RFC-0160:移除對 FIDL 結構預設值的支援

RFC-0160:移除對 FIDL 結構體預設值的支援
狀態已接受
領域
  • FIDL
說明

此 RFC 建議移除在 FIDL 結構欄位指定預設值的功能。

問題
毛皮變化
  • 623161
作者
審查人員
提交日期 (年-月-日)2021-12-29
審查日期 (年-月-日)2022-05-17

摘要

此 RFC 提議移除在 FIDL 上指定預設值的功能 結構體欄位的值

提振精神

目前可以指定結構欄位的預設值,因為 如以下範例所示:

type MyStruct = struct{
  x int8 = 123; // 123 is the default value
};

這麼做的目的,是讓 struct 預設設定成為所有繫結至 將相同的值套用到未指派的欄位, 會在繫結之間產生行為不過,實際上並非如此。 目前,只有 HLCPP 和 Dart 繫結實際上支援 struct 預設值 輕鬆分配獎金事實上,在 Go 等部分繫結中 必須調整網域物件結構,才能支援預設值 因此無法針對欄位的預設值提供語言。

此外,雖然要求和回應結構上的預設欄位值可以 如果您使用 FIDL 語言指定的任何值,系統會忽略這些變數,並為 沒有預設值這不僅是因為缺少 ,但很難在目前的 也能使用 Google Cloud CLI 或 Compute Engine API舉例來說,在 C++ 繫結中,是透過函式呼叫進行回覆 但 C++ 只支援函式呼叫參數的結尾預設引數。

如要新增不一致的狀況,表格和聯集不支援欄位 會因為小工具和新增支援方面的複雜功能而出現預設值 這些可變的類型在繫結和實作方面有更大的差異 比結構更複雜

因此,對於沒有明確路徑的預設設定,系統會提供不一致的支援。 獲得完整的支援服務與其持續提供不一致的 包括全面移除支援

除了實作方面的疑慮,也有概念動機 移除支援的結構體預設值。預設值比較細微 而不是由繫結使用者明確指派的 conss,以及 這種細微的可能性可能會驚嚇使用者,導致發生錯誤使用者 必須知道特定類型的是否有預設值 指定的繫結支援預設值,以及不知道如何使用特定類型, 較複雜

相關人員

講師:hjfreyer@google.com

審查者:

ianloic@google.com、yifeit@google.com

諮詢:

azaslavsky@google.com、mkember@google.com

社交功能:

透過電子郵件討論 eng-council-discuss@fuchsia.dev

設計

您無法在 FIDL 中的結構欄位指定預設值。

實作

目前 13 個 FIDL 程式庫有 119 個結構體預設值的用法,68 個 這些值使用非零的值

此值將在第一期內淘汰,最終 已移除

在淘汰階段,您會看到「@allow_deprecation_struct_defaults」 會導入 (或類似) 註解,以在指定的 檔案。

一段時間後,系統會移除預設值的使用方式,以及啟用的指令 結構體預設值會一併移除。目前,我們將為 已完全移除

成效

不會影響效能。

人體工學

在支援產生預設值的繫結中,這個 RFC 看起來可能 以人因工程學的觀點出發但移除結構體預設支援 可提升繫結之間的一致性,並在許多用途中替換 搭配 const。

回溯相容性

這個 RFC 導致無法支援現有功能,但實作 需要較長的淘汰期,才能減少影響

由於 FIDL 來源之間的相容性異動,這個 RFC 會移除危害 此時結構體的預設值發生變更會導致複雜行為變更 執行起來可能不容易例如,程式碼會明確設定 現在,初始預設值的行為將與未設定的程式碼不同 預設值。此外,在其他情況下 將所有值變更為新的預設值,或是讓所有值 不變。

安全性考量

在某些情況下,移除預設可能會帶來安全性風險,因為 案例預設值可能正在初始化,否則未初始化的記憶體。不過 但實際上並非如此HLCPP 和 Dart,這兩個繫結 目前支援預設值,請確保 struct 欄位已初始化 無論是否提供預設值

因此,這對安全性應該不會產生太大的影響。

隱私權注意事項

這不會對隱私權造成任何影響。

測試

在淘汰階段,將會新增測試,以確保沒有新的結構體 您可以新增預設值

說明文件

結構預設值功能的說明文件將移除。

缺點、替代方案和未知

說明文件的預設值

部分使用者會使用說明文件的結構體預設值取代註解。 預設結構欄位值的好處是更正式的部分 並勾選類型不過,如果沒有預設值 您仍可以記錄 將欄位初始化為 ,但會透過註解或常數來完成 定義。

與常數比較

在使用 const 的情況下,預設值可能優於 const 和預設值。預設值會將值附加至欄位,而非 系統就會改為自動套用預設值 不需要由使用者手動指定

儘管如此,預設值仍可替換為更明確的常數 使用者只要多執行一些工作

較生動的常數

這些常數可能在未來變得更加生動, 就能定義 struct 常數

例如:

type MyStruct = struct { x int8; };

const DEFAULT_MY_STRUCT = MyStruct{ x: 123 };

然後,您可以在繫結中 DEFAULT_MY_STRUCT 複製到變數 (例如 Go 中的 myStruct := DEFAULT_MY_STRUCT) 並做為基礎值使用 以及可設定的欄位這與 結構體,但應能更輕鬆地支援更多繫結。

替代做法:新增更廣泛的預設值支援

建議您考慮對預設值新增更廣泛的繫結支援功能, 取代淘汰的替代方法然而,這並不實際。

請考慮這麼做。產生的結構體如下所示:

type MyStruct struct {
    _ struct{}
    X int8
}

沒有地方可以透過這個 API 自動填入預設值。 此外,欄位不可「取消設定」,因此系統無法偵測 ,並在編碼階段填入預設值。重大 必須重組 API 才能支援預設值。

替代方法:支援 FIDL 零值

Go 等部分語言以及通訊協定緩衝區等編碼格式 3 的概念是零值。也就是說,未初始化的欄位會採用 標準「零」值,通常為 0。

您可以考慮在 FIDL 中新增對零值的支援。就一方面 這可以提升記憶體安全性,但另一方面支援零值 可能與 FIDL 的原則相衝突,建議您「用多少付多少」。 某些情況下或許能避免額外的工作 可能是額外的步驟,確保未設定的值為零。

目前,無論是否初始化欄位,都是繫結層級的疑慮 我們並未規定行為的概略規定。適用對象 執行個體,Go 語言會將所有未設定的 struct 欄位設為零,但 FIDL 不會 確保該情況發生

這樣可能就夠了。取決於 0 值與否,取決於 所以對繫結 API 的繫結行為看似合理 自行決定未設定欄位時會發生什麼情況。只有部分通知 繫結可能會規定所有欄位都必須明確設定 則沒有預設值

大約一半的現有 FIDL 結構體預設值是零,一半則不是。 也就是說,大約一半的現有結構體預設值仍需 否則這些值需要「重新校正」以便集中處理 (例如使用從 0 開始的索引,而非從 1 開始計算)。

各繫結之間共用零值的概念可提供 FIDL 中的值,在部分通訊協定中可能具有重要性, 和其他。在多數情況下,最好能呈現明確 常數。都可以 不論常數值是否為預設值都一樣

這項 RFC 的主要目標是防止過度使用功能故障。 因此,有鑑於此,使用具約束力的零值強制要求 (無價值) 沒有什麼好處? 預設情況下,採用零值概念的做法不包含在 這個 RFC 的設計方式

既有藝術品和參考資料

已在通訊協定緩衝區第 3 版中移除自訂預設值 ( 查看說明文件 ),並替換成零值預設值。 有幾個原因可能會造成這項變動。其中一個原因是 如果未指定預設值,就能使用 「純舊結構體」缺少存取子 (link)。 另一個原因是,我們發現這項工具使用大量 API 預設值為零。

FTP-047「必要表格欄位」遭拒,系統已支援 default 已提議表格欄位的值。這是一個大型提案的一部分 因此拒絕交易不一定表示結果 都應該支援資料表欄位。