LINTを見直した話

僕は基本的にLINTが大嫌いで、理由は

  • いくつかのLINTはあまり上手く実装されていない
  • いくつかのよくあるルールは、プログラミング言語の設計者がわざと導入したルールを制限するものである

という二つが主である。(既に使われているLINTにわざわざ文句は言わないし、開発チームで決めたことには従いますが。)一番ばかばかしいと思うルールの一つに、

  • リストの最後のカンマを入れるか入れないか

がある。これなんかは、設計者がわざわざ導入した自由を逆に制限するものであり、しかも見た目が揃う以外の利点がなにもないルールなので、こういうルールを有効にするのは止めたほうが良いと真顔で発言できる。

で、ずっとLINT嫌いの立場を貫いてきたんだけど、実はLINTって便利じゃないかと思ったことがあるので、書いておきたい。

OCLintのCoveredSwitchStatementsDontNeedDefaultを知って、もしかしたらLINTって便利なものなのかもしれないと、不明を恥じたのだった。これは、Objective-Cプログラムのswitchが網羅的な場合にdefaultがあったら警告するもので、つまり無駄な空のdefaultを書かなくて良くなる効果がある。

switch (enumValue) {
case SomeCase:
  ...
  break;
case AnotherCase:
  ...
  break;
default:
  // Unreachable
  NSAssert(false);
  break;
}

みたいなプログラム、皆さん書きますよね。現時点ではdefaultはいらないんだけど、将来にenumのcaseが増えたことを考えると、defaultを書いておいてせめて実行時にはエラーになって欲しい。でもこのdefaultとか明らかに無駄なので、できればソースコードから無くしてしまいたい。

この葛藤から逃れられるのであれば、LINTは使うべきだなあと思ったのでした。

これは、止めて欲しいと思うルールとなにが違うかというと、

  • 止めて欲しいのは、ある種のプログラムを書くことを禁止するルール
  • 良いと思うのは、コンパイラの賢さが足りないせいで保守的にならざるを得なくてこれまで書けなかったプログラムを、書けるようにするルール

と言える気がする。

なお、OCLintのCoveredSwitchStatementsDontNeedDefaultについて言えば、最近のClangはNS_ENUMとかの新しい構文を使って定義したenumであれば網羅性の検査をしてくれるので、特にOCLintを使う必要はありません。(Cの素朴なenumを書くのを禁止するルールがないかなーと思って眺めてたら見つけました。)