變數名稱計畫

本計畫為「臨時」性質。尚未達成共識。撰寫本計畫的目的是為了收集 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,但它同時指 TargetLoweringTargetLibraryInfo [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 的一個很好的自測機會,並且應該在此過程中修復錯誤,可能包括

  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

[Carruth 首字母縮略詞] (1,2,3)

Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130313.html

[Carruth 駝峰式大小寫] (1,2)

Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130214.html

[Denisov 駝峰式大小寫] (1,2)

Alex Denisov,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130179.html

[Parzyszek 首字母縮略詞] (1,2)

Krzysztof Parzyszek, http://lists.llvm.org/pipermail/llvm-dev/2019-February/130306.html

[Ricci 首字母縮略詞] (1,2)

Bruno Ricci,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130328.html