變數名稱計畫

此計畫為暫定。尚未達成共識。撰寫此計畫的目的是為了捕捉 LLVM 社群的期望和顧慮,並將其形成一個可以達成共識的計畫。原始作者在 LLVM 方面有些天真,因此不可避免地會有一些細節存在缺陷。您可以提供幫助 - 您可以編輯此頁面(較大的更改最好通過 Phabricator 審查),或回覆徵求意見討論串

太長;沒讀

提升 LLVM 程式碼的可讀性。

簡介

目前的變數命名規則指出

變數名稱應為名詞(因為它們代表狀態)。名稱應為駝峰式命名,並以大寫字母開頭(例如 Leader 或 Boats)。

此規則與型別名稱的規則相同。這是一個問題,因為型別名稱不能重複用於變數名稱[*]。LLVM 開發人員傾向於通過在型別名稱前加上 The 來解決此問題

Triple TheTriple;

…或者更常見的是使用縮寫,儘管編碼標準聲明「避免縮寫,除非它們廣為人知」

Triple T;

縮寫的激增導致難以閱讀的程式碼,例如這個

InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width, IC,
                       &LVL, &CM);

許多其他編碼指南[LLDB] [Google] [WebKit] [Qt] [Rust] [Swift] [Python] 要求變數名稱以小寫字母開頭,這與以大寫字母開頭的類別名稱形成對比。這種慣例意味著最易讀的變數名稱也需要最少的思考

Triple triple;

目前規則存在問題已達成某種共識[LattnerAgree] [ArsenaultAgree] [RobinsonAgree],並且縮寫是閱讀新程式碼的障礙[MalyutinDistinguish] [CarruthAcronym] [PicusAcronym]。也存在一些反對意見[ParzyszekAcronym2] [RicciAcronyms]

這個正在進行中的提案是更改變數名稱的編碼標準,要求它們以小寫字母開頭。

變數名稱編碼標準選項

對於以小寫字母開頭的變數名稱,主要有兩個選項:camelBacklower_case。(這些也有其他名稱,但這裡我們使用來自 clang-tidy 的術語)。

camelBack[WebKit][Qt][Swift] 一致,而 lower_case[LLDB][Google][Rust][Python] 一致。

camelBack 已用於函式名稱,這可能被認為是一個優點[LattnerFunction]或一個缺點[CarruthFunction]

camelBack 表示贊成的人有[DenisovCamelBack] [LattnerFunction] [IvanovicDistinguish]。對 camelBack 表示反對的人有[CarruthCamelBack] [TurnerCamelBack]。對 lower_case 表示贊成的人有[CarruthLower] [CarruthCamelBack] [TurnerLLDB]。對 lower_case 表示反對的人有[LattnerLower]

區分變數種類

另一個被要求的變更是區分不同種類的變數[RobinsonDistinguish] [RobinsonDistinguish2] [JonesDistinguish] [IvanovicDistinguish] [CarruthDistinguish] [MalyutinDistinguish]

其他人反對這個想法[HähnleDistinguish] [GreeneDistinguish] [HendersonPrefix]

一個可能性是成員變數以 m_ 為前綴,而全域變數以 g_ 為前綴,以區分它們與區域變數。這與[LLDB]一致。m_ 前綴與[WebKit]一致。

一個變體是成員變數以 m 為前綴[IvanovicDistinguish] [BeylsDistinguish]。這與[Mozilla]一致。

另一個選項是成員變數以 _ 為後綴,這與[Google]一致,並且類似於[Python]。遭到[ParzyszekDistinguish]反對。

減少縮寫的數量

雖然切換編碼標準會使在新程式碼中使用非縮寫名稱更容易,但它並不能改善現有大量廣泛使用縮寫以損害其可讀性的程式碼。此外,新程式碼以周圍程式碼的風格編寫是自然且通常是鼓勵的。因此,儘管編碼標準如此規定,但許多新編寫的程式碼也可能像今天一樣使用縮寫。

除了更改變數名稱的大小寫之外,它們還可以擴展為非縮寫形式,例如 Triple TTriple triple

擴展許多縮寫得到支持[CarruthAcronym] [PicusAcronym],但有一種偏好是延遲擴展縮寫[ParzyszekAcronym] [CarruthAcronym]

社群內部的共識似乎是至少某些縮寫是有價值的[ParzyszekAcronym] [LattnerAcronym]。最常被引用的縮寫是 TLI,然而它既用於指代 TargetLowering 又用於指代 TargetLibraryInfo [GreeneDistinguish]

以下是認為其使用效益超過學習成本的足夠有用的縮寫列表。未在此列表上或用於指代不同型別的縮寫應予以擴展。

類別名稱

變數名稱

DeterministicFiniteAutomaton

dfa

DominatorTree

dt

LoopInfo

li

MachineFunction

mf

MachineInstr

mi

MachineRegisterInfo

mri

ScalarEvolution

se

TargetInstrInfo

tii

TargetLibraryInfo

tli

TargetRegisterInfo

tri

在某些情況下,將縮寫重新命名為完整型別名稱將導致程式碼過於冗長。與大多數類別不同,變數的作用域是有限的,因此其某些目的可以從該作用域推斷出來,這意味著需要更少的單詞來給它一個清晰的名稱。例如,在最佳化傳遞中,讀者可以假設變數的目的是與最佳化相關的,因此 OptimizationRemarkEmitter 變數可以被命名為 remarkEmitter 甚至 remarker

以下是較長的類別名稱和相關的較短變數名稱的列表。

類別名稱

變數名稱

BasicBlock

block

ConstantExpr

expr

ExecutionEngine

engine

MachineOperand

operand

OptimizationRemarkEmitter

remarker

PreservedAnalyses

analyses

PreservedAnalysesChecker

checker

TargetLowering

lowering

TargetMachine

machine

轉換選項

有三個主要的轉換選項

  1. 保持目前的編碼標準

  2. 自由放任

  3. 大爆炸

保持目前的編碼標準

保持目前編碼標準(即完全不轉換)的支持者質疑轉換的成本是否超過收益[EmersonConcern] [ReamesConcern] [BradburyConcern]。成本是 git blame 將變得較難使用;並且合併變更對於下游維護者來說將是昂貴的。請參閱大爆炸以了解可能的緩解措施。

自由放任

編碼標準可以允許 CamelCasecamelBack 兩種變數名稱風格[LattnerTransition]

實作此功能的程式碼審查位於https://reviews.llvm.org/D57896

優點

  • 最初非常容易實作。

缺點

大爆炸

使用這種方法,變數將通過自動化腳本在一系列大型提交中重新命名。

這種方法的主要優點是它可以最大限度地減少不一致的成本[BradburyTransition] [RobinsonTransition]

這與避免大規模重新格式化現有程式碼的政策相悖[GreeneDistinguish]

有人建議 LLD 將會是重新命名的良好入門專案[Ueyama]

保持 git blame 的可用性

git blame(或 git annotate)允許快速識別更改檔案中給定行的提交。重新命名變數後,許多行將顯示為由該一次提交更改,需要進一步調用 git blame 以識別先前更有趣的提交[GreeneGitBlame] [RicciAcronyms]

緩解措施git-hyper-blame 可以忽略或「穿透」給定的一組提交。可以將識別變數重新命名提交的 .git-blame-ignore-revs 檔案添加到 LLVM git 儲存庫根目錄中。目前正在研究是否可以在 git blame 本身中添加類似的功能。

最小化下游合併的成本

LLVM 有許多具有下游變更的分支。合併大規模重新命名變更對於分支維護者來說可能很困難。

緩解措施:大規模重新命名將會自動化。分支維護者可以從重新命名之前的提交立即合併,然後將重新命名腳本應用於他們自己的分支。然後,他們可以再次從重新命名提交合併,通過選擇他們自己的版本來解決所有衝突。這可以在[SVE]分支上進行測試。

暫定計畫

這是大爆炸方法的暫定計畫。尚未達成共識。

  1. 研究改進 git blame。它可以「穿透」提交的程度可能會影響可以進行多大的變更。

  2. 編寫腳本以擴展縮寫。

  3. 實驗並執行各種重構選項的試運行。結果可以發佈在 LLVM Git 儲存庫的分支中。

  4. 考慮證據並就新政策達成一致。

  5. 同意並宣布入門專案 (LLD) 重新命名的日期。

  6. 更新政策頁面。這將解釋新舊規則以及每個規則適用於哪些專案。

  7. 在兩次提交中重構入門專案

    1. 添加或更改專案的 .clang-tidy 以反映商定的規則。(這是在單獨的提交中進行的,以啟用最小化下游合併的成本中描述的合併過程)。同時更新政策頁面上的專案列表。

    2. clang-tidy 應用於專案的檔案,僅啟用 readability-identifier-naming 規則。clang-tidy 也會根據 .clang-format 中的規則重新格式化受影響的行。預計這將是 clang-tidy 的一個很好的「以身作則 (dog-fooding)」機會,並且在此過程中應修復錯誤,可能包括

  8. 收集反饋並適當改進流程。

  9. 將此流程應用於以下專案,每個專案之間有適當的延遲(第一次更改後至少 4 週,隨後至少 2 週),以便收集更多反饋。此列表應排除必須遵守外部定義標準的專案,例如 libcxx。該列表大致按重新命名的時間順序排列。某些項目可能不適合單獨重新命名 - 預計此列表將在實驗後發生變化

    • TableGen

    • llvm/tools

    • clang-tools-extra

    • clang

    • ARM 後端

    • AArch64 後端

    • AMDGPU 後端

    • ARC 後端

    • AVR 後端

    • BPF 後端

    • Hexagon 後端

    • Lanai 後端

    • MIPS 後端

    • NVPTX 後端

    • PowerPC 後端

    • RISC-V 後端

    • Sparc 後端

    • SystemZ 後端

    • WebAssembly 後端

    • X86 後端

    • XCore 後端

    • libLTO

    • 除錯資訊

    • llvm 的其餘部分

    • compiler-rt

    • libunwind

    • openmp

    • parallel-libs

    • polly

    • lldb

  10. 從政策頁面中移除舊的變數名稱規則。

  11. 使用腳本擴展縮寫,重複序列中的許多步驟。

參考文獻

[WebKit] (1,2,3)

WebKit 程式碼風格指南 https://webkit.org/code-style-guidelines/#names

[IvanovicDistinguish] (1,2,3)

Nemanja Ivanovic, http://lists.llvm.org/pipermail/llvm-dev/2019-February/130249.html

[MalyutinDistinguish] (1,2)

丹尼拉·馬柳京, http://lists.llvm.org/pipermail/llvm-dev/2019-February/130320.html

[ParzyszekAcronym] (1,2)

克日什托夫·帕爾齊謝克, http://lists.llvm.org/pipermail/llvm-dev/2019-February/130306.html