ATLAS C++ コーディングスタンダード

これはATLAS C++ Coding Standard Specification (ATL-SOFT-2002-001、2003年7月11日版)の抄訳です。現時点では条項のみ翻訳してあります。解説については上記文書をご参照ください。

目次

  1. イントロダクション
  2. 命名法
  3. コーディング
  4. スタイル

1.イントロダクション

省略

2.命名法

この章では、プログラマーが制御できるすべてのものの名前をどう選び、どう書き、どう管理するかという規則について説明する。

2.1.ファイル名(NF)

NF1
ヘッダーファイルの名前はそのファイルで定義されているクラスの名前に".h"をつけたものでなければならない。(必須)

NF2
実装ファイルの名前はそのファイルで実装されているクラスの名前に".cxx"をつけたものでなければならない(必須)

2.2.意味のある名前(NM)

NM1
ものの名前には、局所的なループ制御変数や配列の引数をのぞき、発音可能な英単語か、実験内で広く使われている短縮語を使うようにする。(推奨)

2.3.不適当な名前(NI)

NI1
非常によく似た名前は使わないようにする。(推奨)

NI2
アンダースコア"_"で始まる名前は使ってはならない。(必須)

2.4.命名規則(NC)

NC1
クラスの非公開データメンバーの名前は"m_"で始まらなければならない。(必須)

NC2
クラスの静的な非公開データメンバーの名前は"s_"で始まらなければならない。(必須)

NC3
パッケージ名につけるプレフィックス(接頭辞)や名前空間の名前をつけるときは、関連するコミュニティの同意を得るべきであり、また、それが妥当なときはPBS(Product Breakdown Structure)に対応するべきである。(推奨)

NC4
クラス間の名前の衝突を避けるために名前空間を用いなければならない。(必須)

NC5
クラス名、typedefで規定する型名、enum型名は大文字で始まらなければならない。(必須)

NC6
変数名や関数名は小文字で始まらなければならない。(必須)

NC7
複数の単語から構成される名前はそれぞれの単語をつなぎ合わせ、二語目以降の単語の最初の文字は大文字にする。(推奨)

NC8
リリースに含まれるすべてのパッケージ名はそれが置かれる階層関係にかかわらず他のものと同じであってはならない。(必須)

NC9
パッケージ名はアンダースコアを含むべきではない。(推奨)

3.コーディング

3.1.プログラムの構成(CO)

CO1
ヘッダーファイルはインクルードガード(多重定義防止)で開始・終了しなければならない。(必須)

CO2
前方宣言で十分なときはそうすべきで、ヘッダーファイルをインクルードするべきでない。(推奨)

CO3
一つのヘッダーファイルでは一つのクラスの(あるいはさらにそれに組み込まれたクラス、それと非常に強く関連したクラスの)定義だけを行わなければならない。(必須)

CO4
実装ファイルでは対応するヘッダーファイルで定義された単一のクラス(あるいはさらにそれに組み込まれたクラス、それと非常に強く関連したクラス)のメンバー関数の定義を行わなければならない。(必須)

CO5
#include文の順番付けをすべきである。(推奨)

3.2.制御の流れ(CF)

CF1
for文のループブロックの中でループ変数を書き換えてはならない。(必須)

CF2
すべてのswitch文はdefault節(ラベルとそれに続く文)を持たなければならない。(必須)

CF3
switch文のすべての節(ラベルとそれに続く文)はbreakで終わらなければならない。(必須)

CF4
一行に収まらないif文は実行文を括弧{}で囲まなければならない。(必須)

CF5
goto文を使ってはならない。(必須)

3.3.オブジェクトの生成・消滅(CL)

3.3.1. 変数の初期化と定数
CL1
可能な限り狭いスコープで変数を宣言すべきであり、その変数は宣言時に初期化するべきである。(推奨)

CL2
式の中ではリテラルを使うべきではない。(推奨)

CL3
異なった型の変数はそれぞれ別個の宣言文で宣言されなければならない。(整数と整数ポインターなど)異なった型の変数を単一の宣言文中で宣言してはならない。(必須)

CL4
スコープの内側と外側で同じ名前の変数を使ってはならない。(必須)

3.3.2.コンストラクタの初期化リスト
CL5
初期化子リストの順番はヘッダーファイルでの宣言の順番と同じであるべきである。:最初に基底クラス、次にデータメンバーを初期化する。(推奨)

3.3.3.オブジェクトのコピー
CL6
それが宣言されたスコープを越えて、局所変数へのポインターや参照を関数が戻り値として返したり、局所変数への何らかのアクセス方法を与えたりしてはならない。(必須)

CL7
もし、クラスのオブジェクトがコピーされるべきではないときは、コピーコンストラクタや代入演算子はprivateと宣言されるべきである。(推奨)

CL8
もし、クラスがポインター型のデータメンバーを持っているときは、コピーコンストラクタ、代入演算子、デストラクタはすべて実装されるべきである。(推奨)

CL10
左辺と右辺のオブジェクトが同一のものであったときにも、代入演算子メンバー関数は正しく働かなければならない。(必須)

3.4.型変換(CC)

CC1
暗黙の型変換は使わず、明示的な型変換を使わなければならない。(必須)

CC2
古いC言語スタイルのキャストではなく、新しいキャスト演算子(dynamic_cast、static_cast)を使わなければならない。(必須)

CC3
constなオブジェクトを非constに変換してはならない。(必須)

CC4
reinterpret_castは使ってはならない。(必須)

3.5.クラスインターフェース(CI)

3.5.1.インライン関数

CI1
ヘッダーファイルは、インラインに出来る小さい関数以外の実装を含んではならない。これらのインラインはヘッダーファイルの最後、クラス定義の末尾の};の後に記述されなければならない。(必須)

3.5.2.引数渡しと戻り値
CI2
戻り値を持つ関数はその関数に渡される引数を変更すべきでない。それによる副作用を避けるべきである。(推奨)

CI3
(1)書き換えできない引数を値で渡せるのは、それが組込型もしくは小さい場合のみにすべきである。(2)それ以外の場合は、constな参照もしくはconstへのポインターとして引数を渡すべきである。(推奨)

CI4
演算子=は*thisへの参照を返さなければならない。(必須)

3.5.3.正しいconst

CI5
関数にポインターや参照の引数を渡す場合、その先のオブジェクトをその関数が変更しないのであればconstとして渡すべきである。(推奨)

CI6
コピーコンストラクタと代入演算子に渡される引数はconst参照でなければならない。(必須)

CI7
クラスメソッドにおいては、プライベートなデータメンバーへのポインターや非const参照を返してはならない。(必須)

CI8
オブジェクトの状態に変化をもたらさないものであれば、そのメンバー関数はconstとして宣言されなければならない。(必須)

CI9
constなメンバー関数にプログラムの状態を変えさせるべきではない。(推奨)

3.5.4.多重定義とデフォルト引数
CI10
引数リストが異なるが同じタスクをする関数にのみ関数多重定義を用いるべきである。(推奨)

3.6.newとdelete(CN)

CN1
newが一度されるとそこから可能なすべての制御フロー中で一つ対応するdeleteがなければならない。(必須)

CN2
関数は、それへ引数として渡されたポインターに対してdelete演算子を適用してはならない。(必須)

CN3
破棄(delete)されたオブジェクトへのポインターや参照にアクセスしてはいけない。(必須)

CN4
ポインターで破棄を行った場合、そのポインターに0を代入しなければならない。(必須)

3.7.静的および大域オブジェクト(CS)

CS1
大域変数を宣言してはならない。(必須)

CS2
二項演算を対称化する場合をのぞいて、大域関数を用いては(定義しては)ならない。(必須)

3.8.オブジェクト指向プログラミング(CB)

CB1
データメンバーをパブリックとして宣言してはならない。(必須)

CB2
一つ以上の仮想メソッドを持つクラスは公開仮想デストラクタもしくは(例外的に)プロテクトされたデストラクタを持たなければならない。(必須)

CB3
仮想関数は、その子クラスにおいてつねに仮想関数であることを再宣言しなければならない。(必須)

CB4
抽象インターフェース以外の多重継承は避けるべきである。(推奨)

CB5
friend宣言の使用は避けるべきである。(推奨)

3.9.アサーションとエラー条件(CE)

CE1
事前及び事後のデータの有効性確認をすべきである。(推奨)

CE2
プロダクション版でアサーションがコンパイルされないことを保証しなければならない。(必須)

3.10.エラー処理(CH)

CH1
情報出力としては標準のエラー出力機能を用いるべきである。cerrやcoutを用いるべきでない。(推奨)

CH2
関数からのエラー報告はすべてチェックしなければならない。(必須)

CH3
状態変数やエラーコードの代わりに例外処理を使うべきである。(推奨)

CH4
関数から、通常でない数値を報告する方法として例外を投げるべきではない。(推奨)

CH5
関数から例外が投げられる場合は、投げられるであろう例外を宣言するために例外記述を用いるべきである。(推奨)

3.11.避けるべきC++の機能(CA)

CA1
malloc、calloc、reallocとfreeは使ってはならない。代わりにnewとdeleteを用いなければならない。(必須)

CA2
stdioで定義された関数は使うべきでない。その代わりとしてiostream関数を用いるべきである。(推奨)

CA3
関数の引数に不定長リスト...を用いてはならない。(必須)

CA4
システムが提供するマクロをのぞき、プリプロセッサマクロは使うべきでない。(推奨)

CA5
#ifdefの使用が許されるのは、非可搬コードのブロックを先導する場合、もしくはCT1にあるようにテンプレート宣言を許す場合に限られる。(必須)

CA6
関連する数値をconstで宣言してはならない。enum宣言を使わなければならない。(必須)

CA7
ヌルポインターを表すのにNULLマクロを使ってはいけない。整数定数0を使わなければならない。(必須)

CA8
const char*や組み込み配列[]を使ってはならない。代わりにstd::stringを使え。(必須)

CA9
union型は使うな。(必須)

CA10
asm(C++のアセンブラーマクロ機能)は使ってはならない。(必須)

CA11
strucキーワードは使うべきでない。(推奨)

CA12
ファイルスコープは使うな。代わりにクラススコープを使え。(必須)

CA13
ブール値に自分専用のtypedefを宣言するな。ブール値にはC++のbool型を使え。(必須)

CA14
ポインター演算は避けよ。(必須)

3.12.読みやすさと保守のしやすさ(CR)

CR1
コードの複製は避けるべきである。(推奨)

CR2
性能のために明快さが犠牲になる場合は必ずコードに説明書きを加えなければならない。(必須)

CR3
typedefを使う場合、それらはprivateまたはprotectedに宣言されなければならない。(必須)

CR4
時間、距離、エネルギーなどはATLAS標準単位を用いてコードを書くべきである。(推奨)

3.13.可搬性(CP)

CP1
すべてのコードはANSIのC++標準に従って書かれなければならない。(必須)

CP2
非可搬なコードは見つけやすく置き換えやすいように書かれなければならない。(必須)

CP3
システム実装で供給されたヘッダー(システムや標準ライブラリのヘッダーファイル)は<>で囲んで読み込まなければならない。他のすべてのヘッダーは""で囲んで読み込まなければならない。(必須)

CP4
includeに絶対パスを書いてはいけない。階層の最下位のパッケージ名とファイル名だけを書かなければならない。(必須)

CP5
includeのファイル名は常に大文字小文字の区別があるものとして扱わなければならない。(必須)

CP6
オブジェクトのメモリー上の配置や寸法についての仮定をするべきではない。(推奨)

CP7
条件式では計算機上の数値表現の精度を考慮しなければならない。floatやdoubleを等号で比較してはならない。(必須)

CP8
関数の引数の評価の順序に依存してはいけない。特に、関数呼び出しの引数に対して++や--演算を施してはいけない。(必須)

CP9
(C++実行時関数ライブラリなど)他に方法があるときはシステムコールを使ってはならない。(必須)

CP10
longを使うべきであり、intを使うべきでない。doubleを使うべきであり、floatを使うべきでない。(推奨)

CP11
リリースに含まれていないコードや、使用が許された外部ソフトウエアのリストにないコードを呼んではいけない。(必須)

CP12
makefileを書いたり拡張したりするのではなく、リリースツールの機能を用いなければならない。(必須)

3.14.C++テンプレート(CT)

CT1
他のクラスと同様にテンプレートは.hファイルで宣言せよ。しかし、その定義はファイルの最後に条件付きで読み込め。(必須)

CT2
テンプレート定義ファイル(.cxx)はライブラリリストから除外されていなければならない。(必須)

CT3
テンプレートはそれを実体化するプログラムでテストされなければならない。そのテストプログラムはライブラリリストから除外されていなければならない。(必須)

CT4
クラステンプレートや関数テンプレートは、それらを実体化する変換ファイルの文脈に依存してはならない。(必須)

4.スタイル

4.1.スタイルの一般的な側面(SG)

SG1
クラスのpublic、protectedおよびprivateセクションはこの順番で宣言されなければならない。おのおののセクションの中で入れ子になった型(enumやclassなど)は最初に現れなければならない。(必須)

SG2
メソッドの出現順序はヘッダーファイルでの順序とソースファイルでの順序が同じでなければならない。(必須)

SG3
文は(行頭の空白をのぞいて)100文字を越えないようにするべきである。可能ならば長い行は複数行に分ける。(推奨)

SG4
一行の長さは(空白やタブも含めて)120文字以内とする。(必須)

SG5
関数宣言では意味のある仮引数を使わなければならない。関数宣言で使われる仮引数名と同じ名前を関数定義で用いなければならない。(必須)

SG6
読みやすさのため、コードは適切に段下げされるべきである。(推奨)

SG7
関数や配列の参照において、[]や()の前に空白を置いてはいけない。また、.と->の前後に空白を置いてはならない。(必須)

SG8
ファイルの中のコーディングスタイルは一貫しているべきである。(推奨)

4.2.コメント(SC)

SC1
クラスやメソッド、フィールド宣言の前ではjavadocスタイルのコメントを用いるべきである。メソッド本体の中では//をコメントとして用いるべきである。(推奨)

SC2
すべてのコメントは完全な(簡潔でわかりやすい)英文で書かれるべきである。(推奨)

SC3
ヘッダーファイルの中では、もし、その関数や属性が、その名前から完全に明らかにならないのであれば使い方をコメントとして記述しなければならない。メソッドが何をするものかをコメントとして記述しなければならない。(必須)

SC4
実装ファイルにおいては、上述のメソッドを実装する際、(それが明白でなければ)メソッドが何を行い、事前条件や事後条件が何かを記述しなければならない。(必須)

(以上)


2007年12月18日