RFC-0036:結構宣告更新

RFC-0036:更新結構體宣告
狀態已遭拒
區域
  • FIDL
說明

為更清楚地傳達重新排序和重新命名欄位對 ABI 的影響,我們建議進行語法變更,為結構體欄位引入序數,並採用與資料表類似的語法規則。

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

拒絕原因

優點

  • ABI 的名稱是否重要令人困惑:xunion、struct 和通訊協定看起來都很相似,但規則不同。

缺點

  • 不過,所有相關人員都認為,與 protobuf 相比,在結構體上導入序數會造成更多混淆,因此這項缺點遠遠不及混淆帶來的影響。

  • 我們也透過其他方式解決「這項變更是否會影響 ABI」的問題,包括:

    • DIFL
    • API 差異,例如程式庫的簽章
  • 名稱對於文字格式 (JSON、FIDLText 等) 很重要,且在此情況下使用訊息時,無法變更名稱。

摘要

為更清楚地傳達重新排序和重新命名欄位對 ABI 的影響,我們建議對結構體欄位導入序數,藉此進行語法變更,並採用與資料表類似的語法規則。

提振精神

我們只專注於成員是否能在各種宣告中安全地重新命名或重新排序,因此存在語法差異,這些差異是自然演變而來,並未傳達任何有關可能變更的 ABI 影響。

此外,目前的結構體宣告語法會導致編譯器難以在發生變更時提供協助和指引

以下列舉幾個範例,這些範例的選擇標準是小型且一致:

struct Name {      table Name {        enum Name {
    T abc;           1: T abc;           ABC = 1;
    U xyz;           2: U xyz;           XYZ = 2;
};                 };                  };

protocol Name {    xunion Name {       bits Name {
    Abc(T t);        T abc;              ABC = 1;
    Xyz(U u);        U xyz;              XYZ = 2;
};                 };                  };

從 ABI 的角度來看,有以下幾點觀察:

  • 重新排序:除了結構體以外,所有項目都可以重新排序,不會有任何影響。
  • 重新命名:
    • struct、table、enum 和 bits 可以重新命名,不會造成影響
    • 通訊協定,且 xunion 的 ABI 會在重新命名後受到影響。

(從來源相容性的角度來看,大多數繫結在重新排序時會來源相容,但在重新命名時則不相容)。

根據這些觀察結果,我們提議為結構體宣告引入序數。上述範例現在會變成:

struct Name {
    1: T abc;
    2: U xyz;
};

具體情形如下:

  • 序數必須從 1 開始,且序數空間不得有間隙 (如果最大序數為 7,則必須存在 1、2、3、4、5、6、7)。詳情請參閱下文
  • 兩個欄位不得使用相同的序數。
  • 欄位序數會決定欄位在結構體中的位置,而非語法位置。
  • v1 中的 JSON IR 沒有任何變更,序數是透過結構體宣告中的成員順序傳達。請參閱第 2 版中 JSON IR 的預計變更。

編譯器指南

為說明編譯器可透過建議語法提供的指引,我們將考量幾個範例並比較其處理方式。

移除欄位 (中間)

No Ordinals        With Ordinals
----------------   -------------
struct Name {      struct Name {
    T abc;           1: T abc;
-   U def;       -   2: U def;
    V ghi;           3: V ghi;
};                 };
----------------   ---------------
Breaks ABI, no     Breaks ABI,
compiler help      compiler error

移除欄位 (結尾)

No Ordinals        With Ordinals
----------------   -------------
struct Name {      struct Name {
    T abc;           1: T abc;
    U def;           2: U def;
-   V ghi;       -   3: V ghi;
};                 };
----------------   ---------------
Breaks ABI, no     Breaks ABI, no
compiler help      compiler help

新增欄位

No Ordinals        With Ordinals
----------------   -------------
struct Name {      struct Name {
    T abc;           1: T abc;
+   U def;       +   3: U def;
    V ghi;           2: V ghi;
};                 };
----------------   ---------------
Breaks ABI, no     Breaks ABI, no
compiler help      compiler error

重新排序欄位

No Ordinals        With Ordinals
----------------   -------------
struct Name {      struct Name {
+   U def;       +   2: U def;
    T abc;           1: T abc;
-   U def;       -   2: U def;
    V ghi;           3: V ghi;
};                 };
----------------   ---------------
Breaks ABI, no     Safe
compiler warning

不允許使用「保留」關鍵字

由於我們要將結構體的序數規則與資料表對齊,因此也可以允許使用「保留」關鍵字。

我們應該採取完全相反的做法:正確剖析保留關鍵字的誤用情形,並提供清楚的編譯器錯誤和說明。For instance "Cannot reserve member in structs. 新增或移除成員會改變結構體版面配置,請考慮改為手動初始化中性成員。

此外,還有其他重要原因應允許使用「保留」關鍵字:

  1. 與資料表不同,在結構體中導入填補時,必須使用明確的大小 (即位元組數);
  2. 在結構體中使用填補是為了非常特定的目的,也就是開發人員需要特定的記憶體配置時。這種情況很少發生,甚至可能不存在,因為 FIDL 版面配置一律為 8 位元組對齊。
  3. 就實作而言,我們已在 RFC-0066:程式設計師諮詢明確預設值中說明,保證特定值會初始化,對特定繫結 (例如 C、LLCPP) 而言要求過於嚴格。因此,如果我們在結構體中導入「保留」的時段,就必須向後端公開,才能向開發人員公開,以利正確初始化。這一切似乎都不必要。

Down the road JSON IR

為了支援欄位排序 (依序數) 和文件排序 (應遵守宣告順序),建議採取下列做法:

  • 以「members」鍵中顯示欄位的順序,代表宣告順序。
  • 導入「序數」鍵,代表序數順序。

設計

未定

導入策略

  1. 導入新語法,同時支援舊語法;
  2. 將所有來源檔案遷移至新語法;
  3. 使用舊語法時新增警告,並提供一週時間,確保不會新增使用舊語法的情況;
  4. 移除對先前語法的支援。

人體工學

本提案透過語法向開發人員傳達 ABI 影響,進而提升人體工學。請參閱下方的相反觀點

說明文件和範例

須符合以下條件:

回溯相容性

這不具備來源層級的回溯相容性。如要進行軟性遷移,請參閱實作策略

效能

沒有影響。

安全性

沒有影響。

測試

fidlc 中進行單元測試,驗證下列項目:

  • 剖析;
  • 序數從 1 開始,且不得有間隙;
  • JSON IR 沒有任何變更。

缺點、替代方案和未知事項

替代方案:資料表的序數雜湊

我們也考慮對表格使用序數雜湊:語法變更會捨棄明確的序數,使結構體成為唯一具有此語法的宣告 (過去是通訊協定和表格)。

首先,明確的結構體序數仍有其優點。 開發人員仍可依語法重新排序欄位,而變更序數則表示 ABI 中斷。

其次,我們不太可能採取探索行動,從表格中移除序數,因為執行階段成本 (效能較低) 與人體工學效益之間的取捨,會超過人體工學效益。

缺點:結構和表格可能會混淆

由於結構體和資料表之間的語法趨於一致,且引入了序數,部分使用者可能會將結構體與資料表混淆,並誤以為移除欄位與 ABI 相容。如果移除結構體中間的欄位,序數序列中會出現間隙,因此會導致錯誤。不過,如果移除序數最大的欄位,則不會發生錯誤。

既有技術和參考資料

未定