読者です 読者をやめる 読者になる 読者になる

C++ におけるコードレビューの重要性と活用

そのような場合 C++ では、この関数 g の仮引数 obj に対して const 修飾を行うことで「私 g は obj の参照先の値に対して破壊的な操作を行いませんよ」という宣言を関数 g にさせることができます。

void g(const LargeObj& obj){ ... }
void f(){
  LargeObj tmp;
  g(tmp); // tmp に対する変更はない
  .....  // tmp に対する何らかの処理(安心です!)
}

やりましたね!

C++ のコードにこの種のコメントを残すのは,コードレビュアーの仕事を増やすお手軽な方法のひとつです.
悪性の const_cast や mutable が問題なのではありません.同僚が悪性の const_cast や mutable をコードに紛れ込ませるようであれば,それは採用プロセスの問題です.
より現実的な問題は,const_cast や mutable のような不穏なキーワードを伴わず,かつコメントやドキュメントと実際の動作が異なる場合です.

#include <iostream>

class LargeObj;
LargeObj* g_obj;

class LargeObj {
 public:
  LargeObj() : id_(0) {
    g_obj = this;
  }
  void IAmNotEvil() const {
    g_obj->id_++;
  }
  int id_;
};

void g(const LargeObj& obj){ obj.IAmNotEvil(); }
void f(){
  LargeObj tmp;
  std::cout << "id = " << tmp.id_ << std::endl;
  g(tmp);  // tmp に対する変更はない
  std::cout << "id = " << tmp.id_ << std::endl;
}

int main() {
  f();
  return 0;
}

現代の C++ 開発では,上記のようなコードのコメントバグを検出するためにコードレビューを用います.これは単純な lint で代替できる作業ではありません.const_cast や mutable というキーワードが使われていないからといって,安易に「tmp に対する変更はない」と結論づけることはできないからです.人力でやることが重要なのです.

この時点で const 参照について「関数引数に const 参照を用いることで、関数が『その関数が参照先の値を書き換えないこと』に言及でき、さらに必要になるまで値のコピーを遅延させることができる」という二つのことが言えますね。

もし仮にこの主張を C++ の const 性と呼ぶのであれば,C++ の const 性はとても良い性質です.その性質はコードレビューによって保証することができます.これが,const 性に気を配る C++ プログラマによるソフトウェア開発において,コードレビューがとても重要な理由です.現実しんどいです…