はじめに
今週 毎週怒り狂っています. 今関わっているプロジェクトは, C++ プログラマがしてはならない ことを全てしています.
用語について,
- オブジェクト: オブジェクト指向でよく知られる. 情報とそれに対する操作を, ひとつにまとめて抽象化したもの. 現実の物とは関係ない, 問題を情報と操作で抽象化する.
フォーマッタで, 強制できない規約を作ってはならない
//----------------------------------
/** 冗長だし, 見やすいと思います?あびゃー
*///--------------------------------
このような規約を守るため, 同僚は一日中"カタカタカタターン"しています. 単純に五月蠅いのでやめていただきたいです. 私が知っているフォーマッタでは対応できないと思います. フォーマッタを使った後で, "このようなフォーマットに補正するPowerShellのワンライナー"を作ってあげたとか, 頭おかしなるで.
copy, and paste をしてはならない
気になってリファクタリングをした結果, 300箇所程度を修正することになりました. 聞くところによると, copy, and paste
を推奨する, 私より歳をとったうましかがいるらしいです. しかも, 2箇所, 不具合にはならないが他と違う箇所が見つかりました, 意味は同じになるコードです. Error~という文字列があるのでほとんど通らないパスと思われます.
もちろん, "やめろや"と言いますが, 二言目には"いや", "でも", "ずっとこうだったし"と言われます.
template<class T>
void add(Base* base, const char* name)
{
add(base, name);
}
template<class T>
Base* find(const char* name)
{
return dynamic_cast<Base*>(find_(name));
}
というコードに対して,
add<Class0>(Class0::Name);
Base* base = find<Class0>(Class0::Name);
300箇所, 該当の2箇所以外は, このようなコードです. 要するに, class Class1
を作ったら, static const char* Class1::Name
を必ず定義するわけです. これもコピペで量産されています, 珍妙なコメントごと.
余談ですが, RTTI
はコンパイラオプションで無効化されているので, dynamic_cast
は意味がないどころか害悪になっています.
stringのコピーをしてはならない
パフォーマンスを気にしなくてよい環境はありますが, このプロジェクトはそうではありません. それどころか, "処理堕ちしたからなんとかして欲しい", と言い出す始末, 訳がわからないです.
"Copy On Write (COW)があるから"という言い訳はとおりません.
autoを正しく理解しなければならない
const std::vector<int>& Class0::getList() const;
に対して,
auto list = class0.getList();
をしてはならない. 言語を正しく理解してないだけです. 勉強する気がないなら, イキリauto はやめましょう.
補足します. 次のようにコメントの意図通りにならないのです.
void initialize()
{
//処理するアイテムを優先度順にソートする
auto list = class0.getList();
std::stable_sort(list.begin(), list.end());
//優先度順に初期化処理をする
for(size_t i=0; i<list.size(); ++i){
}
}
void terminate()
{
//優先度と逆順に終了処理をする
auto list = class0.getList();
for(int64_t i=list.size()-1; 0<=i; --i){
}
}
free
と delete
はヌル値に対して何もしない
SAFE_FREE
, SAFE_DELETE
などと称して, ヌル値でないかチェックしてから解放する処理は意味がありません.
大事なことは次の3点です. これらを犯した場合, SAFE_
なんたらは全く安全ではないです. 1.と 2.が守られていない場合, 全く安全ではないです, 安全であるかのように誤解させる関数やマクロを定義するのはやめましょう, 大事なことなので.
- コピーを禁止にする
- 私の少ない経験では, オブジェクトのコピーが必要になったことはありません
- ディープコピーは, 自ら地獄へダイブする行為なのでしてはいけません
- 画面遷移の際に, ユーザデータをディープコピーしようとした輩がいるので
- ディープコピーは, 自ら地獄へダイブする行為なのでしてはいけません
- swapやmoveで十分, 用に足ります
- moveの実装はswapより難しいため, swapを推奨します
- 確保時に, 確実に初期化する, ヌル値も有効な値です
- オブジェクトの作成時に, 確実に初期化します.
- 解放時に, ヌル値など意味のある値にする
- オブジェクトの破壊時に値を設定することに意味はないですが, デバッグ時に役立つ場合があります
まとめ
TODO: 見つけ次第更新
余談ですが, IDEの多くはデフォルトで TODO
, TODO:
, などを検出するようになっています. TODO_XXX
などの検出にヒットしない書き方は避けましょう.