変数名計画

この計画は暫定的です。合意されたものではありません。これは、LLVMコミュニティの要望と懸念を捉え、合意できる計画にまとめることを目的として書かれています。著者はLLVMのやり方についてやや未熟であるため、必然的にいくつかの詳細に欠陥があるでしょう。ご協力ください。このページを編集したり(大きな変更の場合はPhabricatorレビューを推奨)、Request For Comments スレッドに返信したりすることができます。

要約 (Too Long; Didn’t Read)

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]

この進行中の提案は、変数名のコーディング標準を、小文字で始まる必要があるように変更することです。

変数名コーディング標準オプション

小文字で始まる変数名には、主に 2 つのオプションがあります。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

移行オプション

移行には主に3つのオプションがあります。

  1. 現在のコーディング標準を維持する

  2. 自由放任

  3. ビッグバン

現在のコーディング標準を維持する

現在のコーディング標準を維持する(つまり、まったく移行しない)ことを支持する人々は、移行のコストがメリットを上回るのではないかと疑問を呈しています [EmersonConcern] [ReamesConcern] [BradburyConcern]。コストは、git blame が使いにくくなること、および変更のマージがダウンストリームのメンテナにとってコストがかかることです。考えられる緩和策については、ビッグバンを参照してください。

自由放任主義

コーディング標準では、変数名に CamelCase スタイルと camelBack スタイルの両方を許可する可能性があります [LattnerTransition]

これを実装するためのコードレビューは https://reviews.llvm.org/D57896 にあります。

利点

  • 最初は非常に簡単に実装できます。

欠点

ビッグバン

このアプローチでは、変数は一連の大きなコミットで自動化されたスクリプトによって名前が変更されます。

このアプローチの主な利点は、不整合のコストを最小限に抑えることです [BradburyTransition] [RobinsonTransition]

既存のコードの大規模な再フォーマットを避けるという方針に反します [GreeneDistinguish]

LLDは、名前変更のための良いスタータープロジェクトになることが示唆されています [Ueyama]

git blame を使いやすく保つ

git blame(または git annotate)を使用すると、ファイル内の特定の行を変更したコミットをすばやく特定できます。変数の名前を変更した後、多くの行が1つのコミットによって変更されたものとして表示されるため、以前の、より興味深いコミットを特定するために 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. スタータープロジェクトを2つのコミットでリファクタリングします

    1. 合意されたルールを反映するように、プロジェクトの .clang-tidy を追加または変更します。(これは、ダウンストリームマージのコストを最小限に抑えるで説明されているマージプロセスを可能にするために、別のコミットです)。また、ポリシーページのプロジェクトリストを更新します。

    2. readability-identifier-naming ルールのみを有効にして、clang-tidy をプロジェクトのファイルに適用します。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. 頭字語を展開するスクリプトを使用して、シーケンスの多くの手順を繰り返します。

参照

[Google] (1,2,3)

Google C++ スタイルガイド https://google.github.io/styleguide/cppguide.html#Variable_Names

[WebKit] (1,2,3)

WebKit コードスタイルガイドライン https://webkit.org/code-style-guidelines/#names

[Qt] (1,2)

Qt コーディングスタイル https://wiki.qt.io/Qt_Coding_Style#Declaring_variables

[Swift] (1,2)

Swift API デザインガイドライン https://swift.org/documentation/api-design-guidelines/#general-conventions

[Python] (1,2,3)

Pythonコードのスタイルガイド https://www.python.org/dev/peps/pep-0008/#function-and-variable-names

[SVE]

SVEをサポートするLLVM https://github.com/ARM-software/LLVM-SVE

[IvanovicDistinguish] (1,2,3)

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