OSSのコーディング規約/コーディングスタイル(LLVM/Clang/Swift 編)

第二回目はLLVM/Clang/Swiftプロジェクトのコーディングスタイルを紹介していく。いずれのプロジェクトも同一のコーディング規約を採用しているため、まとめて紹介することにする。

LLVM/Clang/Swift

LLVMは今最も熱いコンパイラ基盤。高い最適化能力が特徴。LLVMはC言語コンパイラであるClangのバックエンド技術としても使われている。Clangは高速なコンパイル性能が特徴。ClangプロジェクトではApple社やGoogle社が様々な場面で関わっている。Apple社のSwift言語もLLVMを採用している。なおSwiftの生みの親はLLVMとClangの開発にも関わっている。いずれもC++と呼ばれるプログラミング言語で開発されている。

サンプルコード

namespace ns {

template <typename T>
class ClassName {
  const char *Data; // メンバ変数もアッパーキャメルケースで記述
  unsigned Length;

public:
  ClassName()
    : Data(),    // コロンは先頭、カンマは末尾に記述
      Length() { // メンバを縦方向に揃える
    switch (0) { // 波括弧は制御文と同一の行に記述
    case 0:      // case文をswitchと同一の列に記述
      break;     // 改行後に処理を記述
    }
  }

  char value() {                  // 波括弧は改行せずに記述
    if (Length == 0) return '\0'; // 波括弧省略・ワンライン化あり
    return Data[Length-1]; // 算術演算時には空白を省略する場合がある
  }

  /// document comment
  template <typename U> int setValue(const U &Val,
                                     unsigned N) { // 仮引数毎に改行
    const char *D = copy(Val);
    Data = D;
    if (N != -1 && // 演算子の末尾で改行
        N != 0)    // このような場面でも波括弧を省略することがある
      Length = N;
    else {
      auto SL = strlen(Data); // 変数名や仮引数名に頭字語を使うことがある
      if (SL > 9); // 常に左辺値を左側に記述
    }
    return 0;
  }
};

} // namespace ns

コーディングスタイルや開発スタイルの特徴

大文字で始まる変数名が印象的。理由は明確にされていないが、おそらくインパクト性の向上やメンバ関数との区別、名前衝突を避ける意図があると思われる。一文字変数の利用やif文のインライン記法、波括弧の省略記法など、レガシー/伝統的な開発スタイルも数多く取り入れられている。流行に惑わされない保守的なスタイルを持ちながらも、書き手の理想を追求するリベラルなスタイルという印象を受ける。要はカオスで癖が強い。

カテゴリスタイル
開発スタイル
インデントソフトタブ(2文字幅)
空行インデント無し
ソースコードの幅制限あり(80文字)※ 印刷時や端末での表示を意識
適切な改行少なめ、詰まったコードが多い
波括弧の省略あり
波括弧の改行あり(開始括弧の前で改行)
if文のインライン化あり(波括弧の省略もあり)
一文字変数あり(大文字)
アクセサゲッター/セッター(`getValue() / setValue()`)
ドキュメントコメント`/// `を利用
コード整列基本的なもののみ(仮引数、OR演算、コメント)
ヘッダファイルソースファイルと別ディレクトリで管理(`./include`)
プログラミング作法
goto文多用する
case文switch文と同一の列に記述
ヨーダ記法無し。大なり比較でも左辺値優先(`v > 9`)
演算処理の空白混在(`a[n-1]`, `v+1`, `a + b`)
改行時の演算子後置(改行の直前に記述)
命名規則
クラス名アッパーキャメルケース
メンバ変数アッパーキャメルケース
メンバ関数ローワーキャメルケース
仮引数アッパーキャメルケース
一時変数アッパーキャメルケース
略称明確な物のみ使う(Loc, Len, tok, Stmt)
頭字語良く使う(`AbCd` → `AC`)
C++スタイル
参照変数側に詰める(`int &v;`)
ポインタ変数側に詰める(`int *v;`)
const左辺値参照constを型名に対して前置する(`const T &v;`)
プライベートメンバ変数クラススコープの先頭で宣言
コンストラクタクラススコープの前方で宣言
テンプレート空白あり、typename使用(`template <typename T>`)
生ポインタ使う(デストラクタでnew/deleteする)
スマートポインタ使う(unique_ptr/shared_ptr)
演算子オーバロードあまり使わない
純粋仮想関数基本使わない
例外使わない
RTTI使わない(実行ファイルの肥大化を避ける意図)
C++スタイルキャストdynamic_castのみ使わない(dyn_castを独自実装)
前置/後置インクリメントバリバリ使う
using namespaceユーザ定義の空間をファイルスコープに取り込む(`using namespace llvm;`)

コーディング規約

LLVM Coding Standards — LLVM 6 documentation(https://llvm.org/docs/CodingStandards.html

ソースコード・リポジトリ

広告
広告