C 言語のコーディング規約


  1. プログラムの設計
  2. ファイルの分類
  3. 名前のつけ方
  4. 関数の作り方
  5. システムライブラリの使用について
  6. 入出力
  7. エラー処理
  8. make
  9. その他

  1. プログラムの設計
    1. プログラムは、拡張性をもつように設計すること。
    2. システムコールからの戻り値は、必ずチェックすること。 (malloc,fprintf,fopen)
    3. 一時ファイルを使うときは、TMPDIR が定義されているか調べ、 あれば、それを使う。
    4. すべてのプログラムは、-v(version) と -h(help) をサポートしなければならない。
  2. ファイルの分類
    1. XXX.h は構造体の定義、記号定数名の定義、マクロの定義、 グローバル変数の定義、関数の定義、 システムのヘッダファイルの include など定義部を入れます。
      複数の XXX.c が使うものをここで定義します。
      また多重に include されてもいいように、先頭と最後に以下の条件を入れます。

      #ifndef _LIBTAKA_H
      #define _LIBTAKA_H
          :
      #endif /* _LIBTAKA_H */
      

    2. XXX.c は、プログラム本体、変数の定義などを入れます。
  3. 名前のつけ方
    1. 意味のある名前をつける(日本語のローマ字表記はさける)
    2. 変数名は小文字を、記号定数名は大文字を使う
  4. 関数の作り方
    1. 関数の定義は1カラム目から始めること。
    2. 入口と出口は1つ
    3. 内部で使うリテラルは必ず #define で定義すること(記号定数)
      プログラムの中に生の数値や文字列を直接書くことは避ける

      特に配列を確保するときのサイズなどは必ずそうすること。

       [例] 
           #define MAX_LBUF      256
           #define SZ_FILE       (sizeof(FILE))
      

    4. コメントを充実させる
      1. 関数の機能説明
      2. 引数、戻り値の説明   
      3. グローバル変数をアクセスする場合は、その説明
      4. 他の API を使う場合は、リターン値、エラー等の情報

       [例] 
      /*-----------------------------------------------------------
          Function : check the member or not in the chk_table
          Return   : 0 -> n   = member
                     -1       = not member  (NOT_FOUND)
        ----------------------------------------------------------*/
      int tblchk(char *chk_tbl[],size_t tbl_size,char *candidate) {
        int    i ;
      
        for (i=0; i<tbl_size; i++) {
          if (! strcmp(chk_tbl[i],candidate))  break;
        }
        if (i == tbl_size)    i = NOT_FOUND;
        return i;
      }
      

    5. ループなどの内部は字下げして、読みやすくする (スペース2,3個)
    6. malloc/free は、基本的には、同一ソースでおこなうこと
    7. 原則的には、1つの関数は100行くらいにおさまるように。
    8. go to 文はエラー処理のための例外以外は使用禁止
    9. デバッグ用の文は #ifdef DEBUG/#endif で囲み、削除しない
    10. 演算子の優先順位を明確にするため、括弧で囲む
    11. 関数からの戻り値は、原則として成功は0、 失敗は0以外の負の値とすること。
    12. プログラムの終了値は、成功は0、失敗は0以外の値とすること。 これは UNIX のきまりです。
      exit(終了値) に正しい終了値を設定すること。 ただし、終了値は 8bit(255 まで) です。
      また、終了値でエラーを分類できるよう、それぞれに対応した値にします。
    13. #ifXXX,#endif を使う場合、 #endif には必ずどれに対応するかをコメントとして書くこと
    14. グローバルな識別子と同じ名前の局所変数を使ってはいけません
    15. 関数の引数は、すべて明示的に宣言すること。int でも。
    16. グローバル変数、静的記憶領域は、明示的に初期化すること。
    17. if 文の条件内では代入しないこと。文の挿入などの拡張ができないから。

      if ((foo = (char *) malloc(sizeof *foo)) == 0)
          die_err("Virtual memory exhausted\n");
      
      foo = (char *) malloc(sizeof *foo));
      if (foo == 0)    die_err("Virtual memory exhausted\n");
      

    18. if 文は、以下のように書いてなるべく行数を減らす

      if (rc == SUCCESS) {
         :
      }
      

    19. switch case 文は、以下の形式で書き、default、break は省略しないこと。

        while((c=getopt(argc,argv,"hf:")) != EOF)
        switch(c) {
            case 'f':
              rtn = optarg;
              break;
            case 'h':
              usage(pname,arglist);
              exit(SUCCESS);
              break;
            default:
              usage(pname,arglist);
              exit(ERROR);
              break;
        }
      

  5. システムライブラリの使用について
    1. システム関数からの戻り値は、原則としてチェックすること。
      それらは、man に記載されているエラーの重大性にかんがみ考慮すること。

      非同期入出力のシステムコールを使う場合は必ず EINTR を再試行すること。

    2. あるシステムに固有なシステムライブラリを使用する場合は、 その関数を wrapper を介して使うこと。
    3. より安全なライブラリコールを使用すること

      ライブラリ 理          由
      snprintf sprintf() は指定された領域をオーバーする可能性がある
      fgets gets() はバッファのオーバーランはチェックしないから
      memset() bzero() は使わない。UNIX としては memset() に統一されつつある

  6. 入出力
    1. stdin,stderr,stdout を使いわける。
  7. エラー処理
    1. エラーは、stderr に出力すること。
    2. エラーメッセージは、以下の形式であること。
      ユーティリティ名:ファイル名:システムからのメッセージ(perror) 等
  8. make
    1. プログラム用のオプション変数は、プログラム名+FLAGS と統一すること。
    2. 以下のターゲットは、必ず作らなければなりません。
      all,install,clean,uninstall
  9. その他
    1. テストは、必ず正常系1、2、異常系など最低でも5種類くらいはすること。
    2. usage() を必ずつくる。
      そのプログラムの使い方を表示する関数です。
    3. README には、以下の項目を明記する
      1. プログラムの使い方
      2. ソースプログラムの名前と機能
      3. make の仕方
      4. ディレクトリ情報
      5. 入力ファイル、出力ファイル、ログファイル等の説明
      6. 改定情報

UNIX の精神

  1. Small is beautiful.
  2. 1つのプログラムには、1つのことをさせる
  3. 効率より移植性を考える
  4. 数値データは ASCII フラットファイルに保存する
  5. シェルスクリプトで効果と移植性を高める
  6. すべてのプログラムをフィルタとして作る
  7. プログラムは小文字で

関連リンク


【 参考書 】

著者本の名前 出版社値段
D.M.リッチー プログラミング言語 C 共立出版
木村泉 プログラム書法

Mike Gancarz UNIX という考え方 オーム社開発局 1600