Zircon 中的 C++

Zircon 樹狀結構中使用了 C++17 語言子集。這包括 核心和使用者空間程式碼C++ 與 C (和部分組語) 混合使用 這兩個地方系統會避免或禁止部分 C++ 語言功能。使用 C++ 標準程式庫功能十分罕見。

語言特色

  • 禁止
    • 例外狀況
    • RTTI 和 dynamic_cast
    • 運算子超載
    • 虛擬繼承
    • 靜態建構的物件
    • 結尾傳回類型語法
      • 例外狀況:具有其他無法中斷傳回類型的 lambda 時必要時
    • 初始化工具清單
    • 核心程式碼中的 thread_local
  • 允許
    • 純介面繼承
    • Lambdas
    • constexpr
    • nullptr
    • enum classes
    • template
    • 預設參數
      • 但請善用判斷力。結尾的選用參數 應該沒有問題可能不是四個選用的布林值引數。
    • 簡單的舊課程
    • auto
    • 多項實作繼承
      • 但要謹慎行事舉例來說,這項技術已廣泛使用,例如:造成乾擾 容器混合
  • 需要進一步管制 TODO(cpu)
    • 全域建構函式
      • 目前我們針對全域的資料結構提供這些資訊。

待辦事項:指標指向風格指南嗎?

C++ 標準版

Zircon 程式碼是以 -std=c++17 建構而成,通常可以使用 C++ 17 語言 和資料庫地圖項目自由運用 (取決於本文提到的樣式/地圖項目限制) 上述及程式庫使用規範 下文)。停留在效期上沒有「一般」疑慮 相容。當標準 C++ 17 功能 都是以最簡潔的方式處理

所有純 C 程式碼 (.c 來源檔案和其使用的標頭) 均為 C 11。只有部分通知 如果程式碼想由樹狀結構外啟動程序重複使用,就屬於特殊例外狀況 載入器,但對於內嵌程式碼而言,使用的是傳統的 C 89 子集。

標準程式庫

C++ 標準程式庫 API 有許多介面,且介面各不相同 我們將標準程式庫 API 細分為 下方列出每種分類的可預測性和複雜性 用於生成及運用特定介面的程式碼 您可以把這些 API 想成 是 C++ 17 API 中最小的 C 類子集。

背景資訊很重要

本節將說明如何評估使用 適用於系統整體的 C++ 程式庫 API沒有任何 硬性和快速規則,但核心除外 (請參閱下一節),但不含 。

因此請謹慎使用

  • 請思考您對時間和空間複雜度、 分配行為 (如有),以及您使用的各個 API 的失敗模式。

  • 接著,思考使用程式碼的特定背景資訊,以及使用方式 該背景環境往往會牽涉到各種疑慮

  • 請特別留意可能快速收到「輸入相依」行為的行為 使用不重要的程式庫設施時,會難以預測。

如果您是在驅動程式庫中編寫主要 I/O 邏輯,或是任何 任何系統服務中的延遲、處理量或可靠性路徑 那麼,您在使用的圖書館設施應該特別保守。 從技術層面來說,這些服務在使用者空間中可供使用 (不過在 核心;請參閱下一節)。但事實上 相關單位會如何運用資料,並讓他們覺得自己 獲得充分告知,且能夠針對該使用方式表示同意您或許不想偏好使用大量支援用途的 std 容器 細膩的動態分配流程這麼做會讓您難以執行 瞭解、預測及控管儲存空間/記憶體用量、分配 服務的行為、效能和穩定性

然而,即使驅動程式庫是使用者空間程式,它也會啟動和剖析 設定檔或引數等等適用於所有非必要或 不屬於熱路徑的啟動時間函式,使用較為複雜的 就比較容易處理的事只要 請務必留意程式碼的整體指標,例如 將執行階段記憶體用量降至最低/總/峰值,程式碼膨脹 (同時使用兩部裝置) 儲存空間和執行階段記憶體),以及不受非預期的故障模式影響。 也許不是只為驅動程式的程式碼大小和記憶體用量兩倍 利用這個精密的設定剖析程式庫

核心中沒有 std

C++ std 命名空間「無法」用於「核心」程式碼, 也包含系統啟動載入程式。幾個 C++ 標準程式庫 不涉及 std:: API 的標頭仍可直接使用。詳情請參閱 。

核心程式碼不應使用其他 C++ 標準標頭。 任何值得在核心中加入的程式庫設施 (例如 std::move) 是透過核心專屬的 API 提供 (例如 ktl::move)。這些 API 的核心實作方式 依賴的工具鍊標頭提供 std:: 實作, 稱為核心 API 名稱但只有這些 API 實作 某些程式庫標頭中非常特殊的情況,應使用 std::

通用標頭

即使在核心中,這些標頭 API 仍可安全使用。

這些程式庫會在標準 C 介面的子集中加入 C++ 包裝函式, 核心支援:

這些標頭中 C 程式庫 API 的 std 命名空間別名不得 用於核心程式碼

即使是在核心中,也可以使用純 C++ 標頭:

保守的使用者空間

這些標頭 API 可以安全使用,我們不允許在 因為全部都是在 std 命名空間中。但子集 如果系統存在,表示這些 API 很可能可取得核心 API 別名 在核心程式碼中使用這類 API 的常見案例

這些只是純標頭類型和範本。不會動態調整 資源分配各項函式的時間和空間複雜度 主題。

這些設定涉及一些動態分配,但僅是明確說明:

  • <any>
  • <memory>

    std::shared_ptrstd::weak_ptrstd::auto_ptr API 應 永不使用。請改用 std::unique_ptrfbl::RefPtr

僅限使用者空間

這些不是任何類似 API 都有提供的功能 或核心名稱但無論如何 使用者空間不支援動態分配。

廚房水槽

這涉及到難以預測的動態分配 掌控權通常他們會遇到確切的執行階段行為和記憶體需求 也很難搞懂在任何服務中使用這些介面前,請務必三思 實現可靠性/效能的重要路徑 「精簡」及「節省空間」

FBL

FBL 是 Fuchsia Base Library,由核心和使用者空間共用。 因此,FBL 具有非常嚴格的依附元件。舉例來說,FBL 不得 因為系統並未 與核心部分相同同樣地,FBL 不得依賴非 C 程式庫功能 有哪些可用的物件?

  1. system/ulib/fbl,可從兩個位置 核心和使用者空間
  2. kernel/lib/fbl,只能從 與核心部分相同
,瞭解如何調查及移除這項存取權。

FBL 提供:

FBL 對記憶體配置設有嚴格的控管規範。記憶體配置 明確,使用 AllocChecker 讓用戶端從配置中復原 失敗。在某些情況下,允許使用隱含記憶體配置, 隱含分配記憶體的函式必須 #ifdef 設為無法使用 核心部分。

平台來源樹狀結構外不支援 FBL。

ZX

ZX 包含 Zircon 物件的 C++ 包裝函式 syscalls 的輔助。這些包裝函式可提供類型安全和移動語意 但沒有提供任何看向 syscalls.abigen 以外的意見。某些 我們可能會從 syscalls.abigen 自動產生 ZX,就像 如何以其他語言自動產生 Syscall 包裝函式

ZX 是 Fuchsia SDK 的一部分。

FZL

FZL 是 Fuchsia Zircon Library。這個程式庫提供 也可以免費對於如何發表意見和看法 會與 Zircon 系統呼叫互動。如果一段程式碼沒有依附元件 Zircon Scalls,程式碼應改以 FBL 顯示。

FZL 不適用於平台來源樹狀結構外。

隱密 C++

我們建議在整個實作語言中使用 C++,而非 C 紫紅色。不過在許多情況下,我們還需要一小的 ABI 瓶頸,才能 可簡化防止、追蹤或適應 ABI 偏移的問題。 第一個確保 ABI 簡單的關鍵方法是以純粹 C API 為基礎, 會直接從 C++ 使用,也可透過其他許多產品的外函式介面使用 而非 C++ API。將程式碼主體連結至 只透過 C++ 模組傳送純粹 C 外部 API 與 ABI 的模組, 稱為密封 C++

  • 據說核心本身可在密封的 C++ 中實作,
  • vDSO 是在密封的 C++ 中實作的共用程式庫。
  • Fuchsia 的標準 C 程式庫,但大多數是 也會在實作時使用密封的 C++。
  • 大部分 Fuchsia 裝置驅動程式都是在密封的 C++ 中實作。

對於從 Fuchsia 公用 SDK 匯出的二進位檔而言,這會是艱難且迅速的規則 共用程式庫必須具備純 C API 和 ABI。這類程式庫 而且應在實作中使用 C++ (而非 C),而且 其他靜態連結程式庫與 C++ API,只要 ABI 考量 這些內部 C++ API 不會洩露到共用資料庫的公開 ABI。

「可載入的模組」(有時稱為「外掛程式」模組) 與 共用媒體庫與單純的 C ABI 瓶頸同樣適用 可載入模組 ABI。Fuchsia 裝置驅動程式就是這類可載入的模組 必須符合驅動程式庫 (純 C) ABI 規格因此, C++ 必須使用密封的 C++。

Fuchsia C++ 工具鍊提供完整的 C++17 標準程式庫 libc++ 實作。在 C++ 執行檔中 ( 使用 C++ ABI 的共用程式庫) 通常會動態連結 這就是編譯器的預設行為工具鍊也提供 libc++:用於密封靜態連結 (透過 -static-libstdc++ 切換至 (clang++)。在 Zircon GN 建構系統中,一個連結目標 例如 executable()test()library() (含 shared = true),採用 此行來要求密封的 C++ 標準程式庫:

    configs += [ "//zircon/public/gn/config:static-libc++" ]

對於匯出至公開 IDK 的每個 library(),此為必填屬性 二進位格式 (透過 sdk = "shared")。

每個 driver() 都會自動使用密封的 C++,因此這一行不會 所需的費用(只能仰賴自己的共用程式庫, 驅動程式庫 ABI 提供的動態連結環境)。

對執行檔和非匯出的共用程式庫來說,這是判斷呼叫 是否針對標準 C++ 程式庫使用靜態連結或動態連結。 Fuchsia 的套件部署模型中並沒有特定的可更新性 改善了共用程式庫的效率。主要 權衡取捨是指儲存大量儲存的記憶體 並使用完全相同的共用儲存空間 資料庫二進位檔案、容器和應用程式 (有時效能) 及 套件。因為系統建構作業中的許多套件都會使用相同的共用項目 libc++ 程式庫,這通常是正確做法 特殊情況這是編譯器和建構系統的預設項目。