初めに
Googleは自社で開発するオープンソースプロジェクトに適用しているスタイルガイドを公開している。
以下の言語が公開されている。
- AngularJS Style Guide
- Common Lisp Style Guide
- C++ Style Guide
- C# Style Guide
- Go Style Guide
- HTML/CSS Style Guide
- JavaScript Style Guide
- Java Style Guide
- JSON Style Guide
- Markdown Style Guide
- Objective-C Style Guide
- Python Style Guide
- R Style Guide
- Shell Style Guide
- Swift Style Guide
- TypeScript Style Guide
- Vim script Style Guide
これらのスタイルガイドはCC-By 3.0で公開されている。
https://creativecommons.org/licenses/by/3.0/deed.ja
以下の2つは別のページにある。
- Effective Dart
- Kotlin Style Guide
見たところライセンスが上のものとは異なっていた。
C++ Style Guide
今回はその中のC++ Style Guideを読み、ヘッダーファイル、命名規則に関する部分についてまとめる。
原文
ttsukiさんによる日本語訳がある。
C++ Version
C++20を使用、C++23は禁止(2025/12/19時点)
非標準の拡張の禁止(GCCの__attribute__)など
Header Files
小さな.ccファイルをのぞく、すべての.ccファイルには対応する.hを作る。
ヘッダーファイルは単体でコンパイルできるようにする(.h)。
The #define Guard
すべてのヘッダーファイルにはインクルードガードをつける。
シンボル名は<PROJECT>_<PATH>_<FILE>_H_の形式
例えばfooに含まれるファイルfoo/src/bar/baz.hは
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_
Include What You Use
対応している.hでインクルードされているファイルは、.ccでも再度インクルードする。
Defining Functions in Header Files
関数が10行以内で短い場合に限り、宣言時に処理を定義できる。
その他の理由で関数を定義する場合、// Implementation details only below hereなどのコメントやinternalという語句を含む名前空間内で定義する。
その場合はinlineなどでインライン宣言されている必要がある。
template <typename T>
class Foo {
public:
int bar() { return bar_; }
void MethodWithHugeBody();
private:
int bar_;
};
// Implementation details only below here
template <typename T>
void Foo<T>::MethodWithHugeBody() {
...
}
Names and Order of Includes
ヘッダーファイルのパスはソースディレクトリからの相対パスで記述する。
その際./や../などは省略する。
インクルードの順序は
- 対応するヘッダーファイル
- 空行
- Cシステムヘッダーとその他の
<>で囲まれ.hを持つファイル - 空行
- C++標準ライブラリ(拡張子を持たない)
- 空行
- その他のライブラリの
.hファイル - 空行
- 自分のプロジェクトの
.hファイル
システム特有のコードはこれらの後ろに記述する。
10.空行
11.システム特有のコード
Naming
snake_case、camelCaseまたはPascalCaseを用いる。
ただしcamelCase、PascalCaseで単語の区切りを大文字化できない場合には_を使用できる。
const int kAndroid8_0_0 = 24;
Choosing Names
省略語(Wikipediaに記載されていない語)は用いない。
ただしその省略語がループ時のiやテンプレートのTなど広く知られた略語の場合は使用可能。
変数の名前はスコープや文脈によって長さを決める。
狭いスコープに対して冗長すぎたり、逆に広いスコープに対して情報のすくない(一般名詞など)名前を用いない。
File Names
ファイル名はすべて小文字と、_または-を使用する。
- ソースファイルには
.cc - ヘッダーファイルには
.h - 特定の場所デインクルードされるファイルには
.inc(非推奨)
テストファイルは
foo_test.ccとする。
Type Names
型名はPascalCaseを用いる。
クラス、構造体、型エイリアス、列挙型、型テンプレート引数はすべてこれに従う。
ただし、classとstructではメンバに対する命名規則が違うので注意。
Concept Names
コンセプトはType nameと同じPascalCaseを用いる。
Variable Names
変数や引数にはsnake_caseを用いる。
Class Data Members
クラスのデータメンバは通常の変数と同様に命名を行い、末尾に_を追加する。
ただしクラスの静的定数メンバはConstant Names
を用いる。
Strict Data Members
構造体のデータメンバは通常の変数と同様に命名を行う。
Constant Names
先頭にkを追加したPascalCaseを用いる。
const int kDaysInAWeek = 7;
Function Names
関数名にはPascalCaseを用いる。
Namespace Names
名前空間にはsnake_caseを用いる。
また、名前空間は名前の衝突を回避しないので、よく知られているトップレベルの名前は用いるべきでない(stdやabslなど)。
Enumerator Names
列挙型の名前はConstant Namesに従う。
enum class UrlTableError {
kOk = 0,
kOutOfMemory,
kMalformedInput,
};
Template Parameter Names
テンプレートの型パラメーターは自身のカテゴリの命名規則に従う。
つまり型テンプレートはType Names
変数の場合はVariable Names
定数の場合はConstant Names
Macro Names
マクロの名前は
MY_MACRO_THAT_SCARES_SMALL_CHILDREN_AND_ADULTS_ALIKE.
(私のマクロは大人も子供も怖がらせる!)
のような名前をつける。
通常マクロを定義するべきではない
画面上のコードとコンパイラが見るコードが変化するので。
必要な場合はすべて大文字の_区切りで、プロジェクト固有の接頭辞をつける。
#define MYPROJECT_HOGE(x)
Exceptions to Naming Rules
既存のC/C++に類似したものがある場合にはそれらの命名規則に従うこともできる。
bigopen()
spares_hash_map
LONGLONG_MAX