Skip to main content
勉強会(第4回)
良い?悪い?コードコメントの書き方




           2009/10/30 さがわ
もくじ
はじめに
コードコメントって何?
コメントはどのように書かれるの?
どのくらいコメントを書けばよい?
コメントはかくあるべき!
実際にコードを改善してみよう
コメントの表記に関してきをつけること
コメントを活用するためのポイント
まとめ
はじめに


「すばらしいコードにはコメントなんて必要ない!」

とは良く言われます。
理想としては、そのような自己解決的なコードを目指すべきです。

ただ、いつもそのようにはいきません。
ときにはコメントが必要になるときもあります。
コメントは良くも悪くもなる諸刃の剣。

どういったときにどのようなコメントを書くべきでしょうか?
コードコメントって何?

コードのコメントなんて誰でも知ってる!
でも、想像以上に考えることが多い、奥深いもの

   // え? こんなのが? 大げさじゃね?
          こんなのが? げさじゃね?
   for (int i=0; i<65535; i++) {



構文上は、コードのコンパイル時に無視される文にすぎないけれど、
コメントの持つ意味の面では、とても重要な役割を果たします。
  アルゴリズムの説明
  保守担当(または、将来の自分!?)への情報提供
  ソース内の目的の位置へ移動しやすいようにするマーク付け
  など。
コメントはどのように書かれるの?

プログラムの言語によって構文は様々
「ラインコメント」と「ブロックコメント」の2種類

                         Javaや
 // これがラインコメント JavaやC++, C#など  C#など
 for (int i=0; i<65535; i++) {

    ここから、                      Javaに
 /* ここから、ブロックコメント JavaにC/C++, C#など         C#など
                         ・・・・・・・・・・ここまで */
 public static void main (String args[]) {

 ' VB系(VB6、VB.NET、VBA、VBScript)はこれ
   VB系(VB6、VB.NET、VBA、VBScript)はこれ    # これはシェルスクリプト
 ' ブロックコメントはないよ                         PerlやRubyも
                                      # PerlやRubyも一緒
 Private Sub Form1_Load()                  れはSQL
                                      -- これはSQL
                                      <!--      HTMLに -->
                                      <!-- で囲むHTMLに -->
                                      <%--      ASP、      --%>
                                      <%-- で囲むASP、ASP.NET --%>
どのくらいコメントを書けばよい?

コメントの量について必ず言えること。
それは・・・、


    「 質であって量ではない! 」
    「 質であって量ではない! 」

ということです。
誤植ではありません。大事なので2行書いてみました。
どのくらいコメントを書けばよい?

コメントは多ければ多いほど良い?・・・答えは×
コメントをたくさん書きすぎると、
  コードの重要な部分が大量の言葉に紛れて見にくくなる
  コードよりもコメントの文章を読み解くのに時間がかかる
                   =質の悪いコード


「必要十分、かつ、最小限のコメントを書く」
「量より質!」

を常に意識してコメントを書くようにする。
どのくらいコメントを書けばよい?

読み手に伝える必要がある情報は…
コメントの記述に頼らず、可能な限りコードで表現する。

コメントには間違った情報が書かれている場合あり、
読み手が信じるのは結局はソースコード。

ソースコード自体を最高レベルのコメントと考えて、
コメントがなくても理解できるコードを書くこと

を心がける。
どのくらいコメントを書けばよい?

すばらしい書き方で書かれたコード
 →コメントを必要としない!
  コードを見れば一目瞭然!

大量のコメントの支えを必要としないコードを書くため

に時間を使う。

※書かなければならないコメントの数が少なければ少ないほど、
 不適切なコメントを書いてしまうおそれも少なくなる。
コメントはかくあるべき!

コメントの内容として何を書くべき?

不適切なコメントは・・・
 読み手に間違った情報を伝えて、誤解を招く原因
となってしまい、コメントをまったく書かないこと
よりもさらに弊害が大きくなってしまいます。

コメントの内容の質を高める上で、重要な留意事項
を説明します。
コメントはかくあるべき!
   ~方法ではなく理由を説明する
    方法ではなく理由を
    方法ではなく理由 説明する


コメントには、プログラムが処理を進めていく
具体的な方法を書くべきではありません。
 →処理の方法や内容はコードを読めばわかる

処理内容の説明ではなく、
   なぜそのように書かれているのか?
という理由や、
    最終的に何が達成されるのか?
を説明する。
コメントはかくあるべき!
     ~方法ではなく理由を説明する
      方法ではなく理由を
      方法ではなく理由 説明する


×      UserRegistryからのデータで
    /* UserRegistryからのデータで
     * Registryオブジェクトを更新する。
       Registryオブジェクトを更新する。
               オブジェクトを更新する
     */


ではなくて、

○      登録情報を  参照できるように
    /* 登録情報を後で参照できるように
       キャッシュする。
     * キャッシュする。
     */


と書く。コードの意図を説明していますよね?
コメントはかくあるべき!
   ~方法ではなく理由を説明する
    方法ではなく理由を
    方法ではなく理由 説明する


コメントを書くときは、どちらの種類のコメントを
書こうとしているのかを常にチェックする。

どちらも同じことだと考えられるけれど・・・
  前者・・・単に内容がわかるだけ
  後者・・・コードの意図が理解できる
と大きな違いがあるのです。
コメントはかくあるべき!
   ~方法ではなく理由を説明する
    方法ではなく理由を
    方法ではなく理由 説明する


保守によってコードに手を加える場合でも、
その修正によって
  コードの存在理由が変化すること
は
  その実現方法を変更すること
に比べれば少ない。

コメントに理由を記述した場合のほうが、
コメント自体の保守作業もずっと楽になる。
コメントはかくあるべき!
    ~方法ではなく理由を説明する
     方法ではなく理由を
     方法ではなく理由 説明する


コメントには

 「方法の説明ではなく、理由の説明を書く。」

また、コメントには「特定の実装方法を選択した理由」を
書くことも考えらます。

あるコードの実装方法として2通りの選択肢があって、
その一方を採用した場合など、その選択の根拠を説明する
コメントがあると良いですね。
コメントはかくあるべき!
     ~コードの内容を言い換えただけの説明は避ける
      コードの内容
      コードの内容を    えただけの説明
                      説明は


 コードの内容をそのまま書いただけ。

×      iをインクリメント
    // iをインクリメント
    i++;


「見たまんまやん!」

と言われそうなコメントは必要ありません。

「コードの内容を単に繰り返すだけの説明を書かない。」
コメントはかくあるべき!
     ~コメントをコードの代用にしない
      コメントをコードの代用
      コメントをコードの代用にしない


 言語自体の機構で強制することが可能な制約

×
       この変数 xxxクラス以外からアクセスしてはならない
         変数に クラス以外
    // この変数にxxxクラス以外からアクセスしてはならない



この条件を言語の具体的な構文で表現することを検討する。
 →public変数を、よりスコープの狭い変数に変更する等
コメントはかくあるべき!
    ~コメントをコードの代用にしない
     コメントをコードの代用
     コメントをコードの代用にしない


次の点にも留意する。
 コードを分割して、適当な名前の付いた複数の関数に分ける
 →ロジックをよりわかりやすく表すことができる場合がある
 変数の用途を説明するコメントを書いてはいけない
 →そのコメントが必要なときは、変数名を適切なものに変更


自分がコードを説明するためのコメントを
たくさん書いていることに気付いたら、
とりあえず作業をやめる。
そして、先に解決する大きな問題がないかを考える。
コメントはかくあるべき!
        つコメントを書
    ~役に立つコメントを書く


優れたコメントを書くには・・・

 →コードの場合と同じで「見直し」と「修正」を
  何度も繰り返しながら質を高める。

ではいったい、どのようなコメントが

        「優れたコメント」

と言えるのでしょうか?
コメントはかくあるべき!
       つコメントを書
   ~役に立つコメントを書く


 読み手にとって意外なコードを説明するコメント

コード内に
  特異な要素や通常は予期しない処理
  読み手にとって意外に思われる記述
が含まれる場合、その部分を説明するコメントを書く。

コードを書いた本人でさえ忘れることが多いので、
あとになって「コメントを書いておいて良かった!」
と実感できます。
コメントはかくあるべき!
       つコメントを書
   ~役に立つコメントを書く


 正しい情報

コメントがコメントでないのはどんなとき?
それは「ウソ」が書いてあるときです。

真実ではない情報を謝ってコメント内に持ち込んで
しまうことは容易に発生し得る問題です。

コメントが記されているコードを修正するときに
とてもありがちなので注意!
コメントはかくあるべき!
         つコメントを書
     ~役に立つコメントを書く


 書く価値のあるコメント

混乱を招くようなコメント、ごく一部の人しか
理解できないコメントを書かない。

コメントはどこで誰に読まれるかわからない!

×
       ここの仕様はオレの脳内にあるので直接聞いて!
          仕様はオレの脳内にあるので直接聞いて
    // ここの仕様はオレの脳内にあるので直接聞いて!

×
    // これ直ってなくない? 後で直してもらうかも
       これ直ってなくない?
コメントはかくあるべき!
         つコメントを書
     ~役に立つコメントを書く


 明瞭である

あいまいな記述は禁物。
可能な限り具体的で明確な内容を書くようにする。

読み手が「これはどういう意味?」と考えこんでしまう
ようなら、それはかえってコードの質を下げている!
×
       とりあえず無限   無限ループでもしときます
    // とりあえず無限ループでもしときます
    while (true) {
コメントはかくあるべき!
         つコメントを書
     ~役に立つコメントを書く


 理解しやすい

読んで理解できるもの。
とくに略語等は読み手を混乱させることがある。

×
         SGGKかどうかの
             かどうかの判定
    // 彼がSGGKかどうかの判定

×
       FPMPの威力を測定する
    // FPMPの威力を測定する
コメントはかくあるべき!
   ~コードの理解に不要な要素を排除する
    コードの理解
    コードの理解に不要な要素を排除する


コメントはその周囲のコードの理解を助けるもの

集中してコードを読むことを妨げるよう要素を
コメントとして書いてはいけません。

次のようなコメントは不要です。
コメントはかくあるべき!
       つコメントを書
   ~役に立つコメントを書く


 過去の情報

以前のコードで使用されていた処理方法の記録を
コメントとして残しておく必要はありません。
 →バージョン管理システムに任せば良いこと

バージョン管理システムを有効に利用する。
コメントはかくあるべき!
       つコメントを書
   ~役に立つコメントを書く


 不要なコード

コードをコメントで囲んで無効化しておくこと。

混乱のもとになるので避ける。
コメントはかくあるべき!
           つコメントを書
       ~役に立つコメントを書く


    ASCIIアート

ASCIIアートの絵や図形などを使った方法でコードを
強調しようとすることを避ける。

×    badExample(n, nyanco(matatabi));
     //            ^^^^^^
     //            私のお気に入りの関数♪
                     のお気       りの関数♪
                                   関数


エディタでプロポーショナルフォントを使用している
場合には、表示がずれるので意味がない。
実際にコードを改善してみよう

実際に簡単なコメントの例を使用して、コードを改善してみます。

例)
×     for (int i=0; i< rlst.size; ++i)
      k(rlst[i]);

     ちょっwwww
         これはひどい。            あるある・・・ねーよww

・・・と、それこそ「ニコ動」でコメントされてしまいそうですね。
コードを見てもわからない、コメントもない。
おまけにインデントされていない・・・。とても残念です。
実際にコードを改善してみよう

コメントを追加して、インデントをそろえました。

○      レシピリストのすべてのレシピを処理
    // レシピリストのすべてのレシピを処理する            処理する
    for (int i=0; i<rlst.size; i++) {
        // レシピをプリントアウトする
        k(rlst[i]);
    }



こうすれば、それほど不可解ではないですね。
ずっと良くなりました。
実際にコードを改善してみよう

さらに、

○   for (int i=0; i<recipes.size; ++i) {
        printRecipe(recipes[i]);
    }


と改善できます。
これならコメントがなくても理解できますね。

※ループ変数の「i」は変更されてないことに注意してください。
 スコープ(有効範囲)が非常に小さいループ変数に名前をつけると、
 かえってコードを読みにくくしてしまうからです。
コメント表記に関してきをつけること

コメントの表記形式については強い信念をもった
プログラマがいたりします。

コメントの表記に唯一なものは存在しませんが、
   「表記形式に関するいくつかの重要な点」
について考慮する必要があります。

ここで紹介する内容は厳格な規則ではなく、
好みに応じて適用するガイドラインとしてください。
コメント表記に関してきをつけること
   ~一貫性


一貫性
すべてのコメントの表記は明瞭であって、
一貫したものである必要がある。

  →開発プロジェクトでスタイルが定めら
   れている場合はそれに従うこと。

既存の優れたコードの記述を調べて、
そのスタイルに習うのも良い方法です。
コメント表記に関してきをつけること
       明瞭なブロックコメント
      ~明瞭なブロックコメント


    明瞭なブロックコメント
    コメントがコードの間に割って入って、
    ロジックの流れを断ち切ってはダメ。
×    /*
     複数行からなるコメント
         からなるコメント。
     複数行からなるコメント。
        こんな書
        こんな書き方だと
     わかりづらいですね。
     わかりづらいですね。
     */


○    /*
         大量のコード
           のコード内
      * 大量のコード内にブロックコメントを
         配置するときは このように書
           するときは、
      * 配置するときは、このように書いたほうが
         格段に みやすくなる。
      * 格段に読みやすくなる。
      */
コメント表記に関してきをつけること
       ~コメントのインデント


    コメントのインデント
    コメントがコードの間に割って入って、
    ロジックの流れを断ち切ってはダメ。
×    private void strangeCommentStyle() {
         for (int i=n; i<JUST_ENOUGH_TIMES; i++) {
        これは次        のコメント。位置がずれてて
     // これは次の行のコメント。位置がずれてて分かりにくい   がずれてて分
             doSomethingMeaningful(i);
           のこの行にあったらわかりにくい。
     // 上のこの行にあったらわかりにくい。
             anotherUsefulOperation(i);
         }
     }
コメント表記に関してきをつけること
        保守の負担が いスタイルを選
       ~保守の負担が軽いスタイルを選ぶ


    保守の負担が軽いスタイルを選ぶ
    コードを書くための時間をコメントの手直しに消費
    してしまうようなコメントは書かない。

×
     /************************************************
      * こんなコメントだと                                    *
          右側」
      * 「右側」を直すのが                                    *
        たいへん・・・。
      * たいへん・・・。見た目は綺麗だけれど・・・。  綺麗だけれど・・・
                                    だけれど・・・。         *
      ************************************************/
コメント表記に関してきをつけること
          ~フラグ


    フラグ
    コメントはコード内にインラインのフラグとして
    使用することができる。
    マークして置くと、後からカンタンに検索をすることができる。
    これは開発ツール(VisualStudioやEclipse)の機能として搭載さ
    れているので積極的に活用する。
○               初期化処理を追加する
                         する。
       // TODO: 初期化処理を追加する。
                  不具合発生のため
                       のため、
       // UNDONE: 不具合発生のため、現在対応中
       // HACK: パフォーマンス改善する。
                パフォーマンス改善する。
                        改善する

※Visual Studio(C#)のコメント・トークン例
  TODO・・・未実装 / UNDONE・・・未完成/ HACK・・・要改変
    参考:http://www.atmarkit.co.jp/fdotnet/dotnettips/163vsjump2/vsjump2.html
コメント表記に関してきをつけること
  ~ファイルヘッダとしてのコメント


ファイルヘッダとしてのコメント
ソースファイルの先頭には、そのファイルの内容を
説明するコメントブロックを必ず書くべきです。
 ファイルの概要、目的
 所有者、著作権

逆に、
最新の情報が反映されない状態に陥りがちな情報
はヘッダに書くべきではありません。
 修正者名
 最終更新日

これらはバージョン管理システムを参照する。
コメントを活用するためのポイント

コメントは・・・
 →コードを書くときに欠かせない便利な道具

しかし、コメントを使用するときは、
誤った使い方をしないように十分注意しましょう。
コメントを活用するための注意点
   ルーチンを書
  ~ルーチンを書くためのコメント


ルーチンを書くためのコメント
 先にルーチンの構造にしたがってコメントを書く場合
 →コードを書き終えた時点で、最初に書いた各コメン
  トがまだ有効かどうかを確認する

 後でコメントを追加する場合
 →適切なコメントを書く作業を忘れないようにする

理想的なのは・・・
 コードを書きながら並行してコメントを書くこと
です。
コメントを活用するための注意点
       バグの修正通知
      ~バグの修正通知


    バグの修正通知
    バグを修正したときに、そのことを通知するための
    コメントを書くことが習慣的に広く使われますが・・・
     →これは望ましい使い方ではない!
×
     // 管理番号 B11840
        blah.func()メソッドは処理が適切にできていなかったため
                   メソッドは処理
     // blah.func()メソッドは処理が適切にできていなかったため
        blah.func2()を使用するように変更した
                       するように変更
     // blah.func2()を使用するように変更した
     blah.func2();


このようなコメントは善意で書かれたものでも、
結果的に有益な効果よりも弊害をもたらすことが多い。
コメントを活用するための注意点
    バグの修正通知
   ~バグの修正通知


 バグの修正通知(つづき)
 バグを本当に理解するために
  →BTS(バグトラッキングシステム)でバグを検索、
   修正前のリビジョンファイルを取得し調査する
   等が必要になってしまう。

実際には、そのようにバグ修正が行われたことを
まったく知らなくても特に問題はなく、そのほうが
かえって効率的に作業を進められます。
コメントを活用するための注意点
   バグの修正通知
  ~バグの修正通知


バグの修正通知(つづき)
このようなコメントをいったんつけ始めると、
開発の終盤や保守の段階に至った頃にはその数が
大幅に膨大しています。

 賞味期限切れの情報
 読み手のコードへの集中を妨げて、
 主要な実行の流れを読み取りにくくするような情報

が、ソースコード中に散らばっているという状態に
なってしまう。
コメントを活用するための注意点
   バグの修正通知
  ~バグの修正通知


バグの修正通知(つづき)
一見しただけでは気づきにくい修正を行った場合、
後でコードに手を加えようとするプログラムが再び
同じバグを作り出してしまうことを防ぐために
コメントを挿入すべきだという主張もあります。

しかし、そのような本当に説明が必要とされる
ごく限られた場合のコメントの使用は、
バグ修正の通知ではなく、むしろ「読み手にとって
意外なコードを説明する」ことを目的としたものと
考えるべきです。
コメントを活用するための注意点
   コメントの劣化
  ~コメントの劣化


コメントの劣化
コメントは劣化します。
コメントに限らず、保守が行き届いていないコードは
劣化しやすく、放っておけば時と共に欠陥が増えます。

コメントの劣化は、コードのほかのどの要素よりも
ずっと急速に進み、その説明の対象であるコードと
同期されていない古いものになりがちです。

コードの変更時には、そのコードに付けられて
いるすべてのコメントを適切に更新する。
コメントを活用するための注意点
    コメントの劣化
   ~コメントの劣化


 コメントの劣化
 コードブロックをコメントアウトしたまま残さない。
 コメントアウトされているコード
  未完成のまま放置されている修正コード?
  作業がまだ進行中?
  最終的にうまくいかなかった?
   →そのコードを読む他のプログラマを混乱させる。
    書いた本人でさえ、一定期間を過ぎたあとに見ると
    意図のわかりにくいもの。

そのようなものがある場合、注釈を付けるか、
コードを完全に削除するべきです。
コメントを活用するための注意点
    保守段階のコードの無意味なコメント
        のコードの無意味
   ~保守段階のコードの無意味なコメント


 保守段階のコードの無意味なコメント
 保守段階においては、無意味なコメントを見つけて
 も、それが危険なコードである場合以外は、削除せ
 ずにそのままにしておく。
  →それが危険なコードであるという情報になり、
   将来の保守担当への警告となる。

事実として間違っているコメントや、誤解を招く
おそれがあるコメントは、コードの保守作業の一環
として適切に訂正をする。
コメントを活用するための注意点
    保守段階のコードの無意味なコメント
        のコードの無意味
   ~保守段階のコードの無意味なコメント


 保守段階のコードの無意味なコメント
 各種有用なコメントフラグの意味を理解して、
 それらに対して十分に関心と注意を払う。

 コメントアウトされたまま残っている出力ステート
 メントにもきをつける。
  →それは、過去にその周辺で問題が発生した
   ことを示す確かな証拠!

常にコードを信じて、
コメントを疑うことを忘れないように!
まとめ
コメントは量より質!
より少なく、良質のコメントを書くように努める
理由を説明するコメントを書く
コメントをたくさん書くより、優れたコードを書く
ことに集中


  保守フェーズのことをよく考える
参考文献


Pete Goodliffe『Code Craft~エクセレントなコードを書くた
めの実践的技法~』、 毎日コミュニケーションズ 、2007年。