ローカル変数には const や final を付ける

変更しないローカル変数には、const とか final を付けるべきだ。そして、ローカル変数を変更しないようなプログラミングスタイルにしてもらえると、レビューが楽で助かる。
もちろん、ループカウンタなんかは const にはできない。絶対にできないわけではないけれど、Haskell じゃあないんだし、そこまでしなくてもいい。
ローカル変数に付ける constfinal は、シートベルトみたいなもの。カッコ悪いとかメンドいとか馬鹿なこと言ってないで、いいから付けなさい。

引数にも const や final を付ける

ローカル変数には constfinal を付けるわけだが、関数 (メソッド) の仮引数というのは一種のローカル変数なわけで、やっぱり、const やら final やらを付けるべきだ。
C++ でも Java でもこれらの型修飾子はシグニチャには影響しないので、API 仕様が汚れたりはしない。「やっぱり const/final やーめた」となったら、こっそり消して構わない。
C++ で前方宣言をする場合は、こんな感じにするといい:

前方宣言

T do_something(U argument1, V argument2);

実体定義

T do_something(U const argument1, V const argument2)
{
    // 実際の処理
}

const は「実際の処理」の中で引数((厳密に言えば、「実引数で初期化されたローカル変数」。こう捉えると、const にも納得 (してください)。))が変更されないことの表明なので、宣言に書いても無意味。だから書かない。「U const argument1」は、キモいかもしれないが正当な書き方で、「const U argument1」と全く同じ。敢えてこう書くのは:

  • const U& argument1」の間違い?、と思われないように。
  • 宣言の「U argument1」との呼応。
    • 「実装上の詳細を言わせてもらえれば、この argument1 っていう変数は const なわけなんですよ。」という呟き的なニュアンス。
    • “実装上の都合”なので、使う側の視点である宣言には現れない。

とまあ、これだけ書いておいて何ですが、引数を値渡しするのはレアケースですね。

const じゃなくて variable があればいいのに

const をやれ「ローカル変数に付けろ」「引数にも付けろ」と主張していると、「うぜー」と思われる((const がうざいのであって僕がうざいのではない、と信じたい。))。そういうとき、いつも思う:

  • あぁ、デフォルトが const で、どうしても変更可能にしたい変数にだけ variable って書くんだったらいいのに

他にも、こうも思う:

  • どうしても仮想にしたいメソッドにだけ virtual って書くんだったらいいのに*1
  • どうしても継承可能にしたいクラスにだけ nonfinal とか unsealed って書くんだったらいいのに。
  • どうしても暗黙の型変換を許したいコンストラクタにだけ implicit って書くんだったらいいのに*2

*1:C# はエラいと思う。

*2:やっぱり、C# はエラいと思う。