SDXFrameWork  0.13
SDXFrameWork
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
SDXコーディング規則


はじめに

普通にコードを書いた後、コード分析のために作成した資料です。
同じような事をしてるのにやたらバラバラな事をしていたり、よく考えると不自然な書き方をしていないかをチェックするために書いています。

 数ページの規約を守れば誰でも分かりやすいコードが書けるなんてことはないです。
例えば、「yes/noを表す変数はintで無くboolを使おう」とか「NULLじゃなくnullptr使おう」とか常識的な事は規約に書く意味は薄いです。
こう言う事を書いても無駄に規約が長くなって読むのが面倒になるだけです

 なので本規約は「複数のコーディングスタイルがありどちらも大した差がないので、どちらかに統一する」事が主眼に置いています。
例えば、インデントを4か8にするかTabにするか空白にするかは大した差が無いかもしれませんが、少なくとも同じプロジェクト内ではどちらかに統一した方が良さそうと言った具合です
ついでに言うとスタイルを統一してもそこまで可読性は上がりません、レビューするのが一番大事です

 また特殊な事情で制限をかけている事が少しあるので、その辺りの注意等も書いています

基本方針
①C++初学者のために初歩的な構文だけ使うとか考えない
②仮引数以外の日本語識別子は基本的に避ける
③規約に問題があれば見直しを行う

適用範囲
SDXのみ対象です。
派生ライブラリやサンプルコードは命名規則に準拠せず、英語以外の識別子を必要な時に使います。
また、こう言う方針で書いてると言うだけなので、プルリクエストする時にここの規則に合わせる必要もないです
もしプルリクエストが来たら、規則から外れ過ぎないように修正するか、規則を見直します
またレビューを厳密に行っていないので、多少は方針に従っていないコードがあります

参考
以下のページや書籍等を参考にしたり反面教師にしたりしています
クラスライブラリ開発のデザインガイドライン
Google C++スタイルガイド
Effective C++(書籍)

命名規則

基本
無理の無い範囲でわかりやすくする。一般的ではない省略は行わない。
RandamをRandとしたりしているが、これは歴史的経緯があるし別に良いか?

ファイル名
ヘッダーファイル名は、クラス名と同じにし拡張子は.hにし.hppにしない。

仮引数
 基本的に日本語にします。
Unicode範囲内の特殊な記号は使いません
句読点などの規格非準拠な文字は使いません

仮引数以外の識別子
 それ以外は半角英数とアンダーバーで命名します
ローマ字表記は避け、英単語を元に命名します
基本的に英語ですが、例外としてprivateな変数とローカル変数名は日本語にする事もある

大文字と小文字の使い分け
 先頭と単語の区切りを大文字にするのをPascal形式と言い、先頭を小文字にし単語の区切りを大文字にするのをCamel形式と言います。

 クラス、構造体、メンバー関数、列挙体、列挙子、ローカルで無い定数はPascal形式

 ローカル変数とメンバー変数はCamel形式

 マクロはすべて大文字にして_で単語をつなぐ。ただし、マクロは必要な時だけ使います。
名前空間は全て大文字にし_で単語を繋ぎます。

慣用的な命名
 ループカウンタはa,b,cの順で一文字の変数を用いる、ループは極力減らす、とりあえず3重以上のループは書いていない。
範囲ベースのループは for(auto it: hoge)とかfor(auto & it:hoge)とかfor(const auto &int :hoge)とかにする
テンプレート仮引数の前にはTを付ける

スタイルの統一

ヘッダーファイル
 基本的にはヘッダーファイルで実装と宣言をする。
実装が不可能な場合は実装と宣言を分ける
前方宣言で十分な場合、無闇にincludeしない
(コード毎に最適化する関係で実装と宣言を分けた方が良いかもなので、方針転換はありえます)

可変数引数
 可変数引数は使わず可変テンプレートを使います。
抽象クラスのメンバー関数に可変数引数が必要な場合は、可変テンプレートで初期化可能な型を引数にします
文字列の場合はVariadicStreamを使います

インライン関数
 inlineキーワードは使わず、コンパイラの判断にまかせたいのですが、
明示的に書かないとinline化してくれない事があったので必要なら使います。

インクルードガード
使いたいコンパイラが全て pragma onceを実装しているため。
defineによるインクルードガードではなく、pragma onceを使う。

キャスト
int,float,doubleの相互変換はcスタイルキャスト可。
それ以外はc++スタイルのキャストを使う。

その他

著作権表示
コードの先頭には著作権表示を以下三行でコメントする
Copyright © 2014 SDXFramework
[License]GNU Affero General Public License, version 3
[Contact]http://sourceforge.jp/projects/dxframework/

 ライブラリのコードなのかユーザーが書いたコードなのか見分けをつけやすくするのと、
権利を明示的にするため必要です

機種依存文字(というかフォント依存文字)の©を使うのは、MSVCでUTF-8で確実に保存するためです。
名前空間
グローバル変数は作らず、少なくともSDX名前空間に入れる。
using namespace std;は使わない

仮想クラス
純粋仮想関数を1つ以上持つクラスは、先頭にIをつける。
メンバー変数を持っていてもIを付ける

Get、Set
代入か取得の片方しかしないメンバー変数はプライベートにし、Get関数とSet関数を作る。
GetとSetの両方をしたい場合はpublicにしても良い

宣言の順番
まずprivate、次にprotected、そしてpublic
変数の宣言ののち関数を宣言する
そんなに重要ではない

入出力ストリーム、文字列ストリーム
ライブラリ内部では使う、利用者は使用せずにライブラリを使えるようにする。

前置インクリメント
最適化されてもされなくても速度差は殆ど無いが
デバッグビルドもあるので一応前置インクリメントに統一したい

float型
基本的に使わない、doubleにしている


Boost
標準ライブラリを優先して使い、必要な場合はboost等を使う。

C++11/14/1z
VisualStudio最新版とclang3.3で対応している範囲のみ使用可能。

コメント
ソースコード管理システムに登録されるような事は書かない。
仮引数と戻り値用のドキュメントコメントは使わない
関数とクラスには一行以上の説明を必ず付ける
クラスに対してはテストコードをサンプルコードとして付ける
変数と列挙子は必要なら一行で説明をつける。コメントなしで分かる変数名にするのが良い。
コメントアウトしたコードは速やかに削除する
実装途中の関数は[@todo]タグを付けておく

実装コメント
分かりにくい場合、関数内部に説明のコメントをつける。
テスト兼サンプルコードについては詳細に付ける方が良い

コード整形
CodeMaidで整形した形を標準にする?

インデント、スペースとタブ
タブ幅は4とし、空白では無くタブを使う

括弧
括弧と括弧閉じは同じ高さ、あるいは同じ行にする。例外としてelseを使う場合は以下の書き方をする事もある。

//ダメ
if( x == 1 ){
func();
}
//良い
if( x == 1 )
{
func();
}
//良い
if( x == 1 )
{
func();
}
else
{
func2();
}