style(9) FreeBSD 一般コマンドマニュアル

style

前のページ 上に戻る 次のページ

style


     記しています。これはユーザランドのコードスタイルの手引きでもあります。

     /*
      * FreeBSD のためのスタイルガイドです。
      * CSRG の KNF (Kernel Normal Form, カーネル標準書式) に基づいています。
      *
      *      @(#)style       1.14 (Berkeley) 4/28/95
      * $FreeBSD: src/share/man/man9/style.9,v 1.32.2.14 2001/08/17 13:08:54 ru Exp $
      */

     /*
      * とても重要な 1 行のコメントはこのようにします。
      */

     /* 殆どの 1 行のコメントはこのようにします。 */

     /*
      * 複数行にわたるコメントはこのようにします。実際の文章を書きます。実際の
      * 段落に見えるように埋めていきます。
      */

     著作権ヘッダの後には空行を 1 行入れ、ソースファイルには rcsid を付けま
     す。バージョン管理システムの ID タグは、ファイル中に 1 個のみあるべきです
     (このファイルでは違いますが)。 C/C++ ソースファイル以外はこの例に従います
     が、 C/C++ ソースファイルは以降の例に従います。外部から入手したファイルの
     すべての VCS (バージョン管理システム) リビジョン識別子は、維持します。こ
     れには、ファイルの来歴を示す複数の ID も含みます。一般的に、`$' も含め
     て、ID はそのままとします。ほとんどの非 FreeBSD の VCS ID は、コメント中
     ではタブでインデントされているでしょう。

     #ifndef lint
     #if 0
     static char sccsid[] = "@(#)style       1.14 (Berkeley) 4/28/95";
     #endif
     static const char rcsid[] =
       "$FreeBSD: src/share/man/man9/style.9,v 1.32.2.14 2001/08/17 13:08:54 ru Exp $";
     #endif /* not lint */

     この後に空行を 1 行付けます。

     カーネルのインクルードファイル (すなわち、sys/*.h) が初めに来ます。通
     常、<sys/types.h> または <sys/param.h> のどちらかが必要ですが、両方は必要
     ないでしょう。 <sys/types.h> は <sys/cdefs.h> をインクルードしており、依
     存関係は問題ありません。

     #include <sys/types.h>          /* 山括弧による非ローカルインクルード */

     ネットワークプログラムである場合は、次にネットワークインクルードファイル
     を置きます。

     #include <net/if.h>
     #include <net/if_dl.h>
     それから、空行があって、ユーザインクルードファイルが来ます。

     #include "pathnames.h"          /* " " によるローカルインクルード */

     アプリケーションインタフェースを実装している場合を除き、実装の名前空間で
     #define したり名前を定義したりしてはいけません。

     ``安全でない'' マクロ (副作用を持っているもの) の名前と、明らかな定数のマ
     クロの名前はすべて大文字です。式のように展開されるマクロは、単一のトーク
     ンにするか外側に括弧をつけます。 `#define' とマクロ名の間にタブ文字を 1
     個入れます。マクロがある関数のインライン展開である場合は、関数名は全て小
     文字で、マクロはすべて大文字の同じ名前を持ちます。マクロが 1 行以上必要な
     場合は、ブレース (`{' と `}') を使用します。バックスラッシュは右揃えしま
     す。こうすると読みやすくなります。マクロが複合文をカプセル化する場合に
     は、それを ``do'' ループで囲みます。これにより、 ``if'' 文で安全に使用で
     きます。最後の文の終端のセミコロンは、マクロではなくマクロの実施時に付け
     られるべきです。これにより、清書器やエディタで文法解析しやすくなります。

     #define MACRO(x, y) do {                                                \
             variable = (x) + (y);                                           \
             (y) += 2;                                                       \
     } while(0)

     列挙値は全て大文字を使用します。

     enum enumtype { ONE, TWO } et;

     構造体の中で変数を宣言する時には、使用順、サイズ順、アルファベット順にソ
     ートして宣言します。最初の区分は通常適用しませんが、例外があります。各宣
     言は、それぞれ独立した行にて行います。最初の語の後にタブ文字を 1 個置きま
     す、すなわち `int^Ix;' と `struct^Ifoo *x;' です。

     重要な構造体は、それが使用されるファイルの先頭で宣言されるか、複数のソー
     スファイルで使用される場合は別のヘッダファイルで宣言されるべきです。構造
     体がヘッダファイルで宣言されている場合には、それら構造体の使用は、宣言と
     は分けられるべきで、かつ "extern" であるべきです。

     struct foo {
             struct  foo *next;      /* 使用中の foo リスト */
             struct  mumble amumble; /* mumble のコメント */
             int     bar;
     };
     struct foo *foohead;            /* グローバルな foo リストの先頭 */

     可能な時には必ず、あなた自身でリストを操作するのではなく、 queue(3) マク
     ロを使用してください。従って、前の例をより良く書くと次のようになります。

     #include <sys/queue.h>
     struct  foo {
             LIST_ENTRY(foo) link;   /* foo リスト用のキューマクロの糊 */
             struct  mumble amumble; /* mumble のコメント */
             int     bar;

     全ての関数はどこかでプロトタイプされます。

     私的な関数 (すなわち、他のどこでも使用されない関数など) の関数プロトタイ
     プは、最初のソースモジュールの先頭に置かれます。単一のソースモジュールに
     ローカルな関数は、 `static' で宣言されるべきです。

     カーネルの別の部分から使用される関数は、関連のあるインクルードファイルの
     中でプロトタイプされます。

     複数のモジュールでローカルに使用される関数は、 extern.h 等の分離したヘッ
     ダファイルの中に置かれます。

     一般にソースファイルが K&R 旧約聖書コンパイラでコンパイル可能である (べ
     き) 時にのみ、インクルードファイル <sys/cdefs.h> の __P マクロを使用しま
     す。新しいコードでの __P マクロの使用は反対されていますが、既存のファイル
     に対する修正はそのファイルの規約と首尾一貫しているべきです。

     ファイルの 50% かそれ以上を巻き込んだ修正の場合は、一般にコードは ``新し
     いコード'' とみなすことができます。これは既存のコードの慣例を破り、現在の
     スタイルガイドラインを使用するのに十分です。

     カーネルはパラメータの型に関連付けられた名前を持ちます。例えば、カーネル
     内でこのように使用します。

     void    function(int fd);

     ユーザランドのアプリケーションに対して見えるヘッダファイルの中では、可視
     のプロトタイプは、型を伴った保護された名前を使用するか、型だけで名前を使
     用しないかのどちらかが必要です。保護された名前の使用がより望ましいです。
     例えば、このように使用します。

     void    function(int);

     または

     void    function(int _fd);

     プロトタイプは関数名の行揃えを行なうために、タブの後に追加のスペース文字
     を置いても構いません。

     static char     *function(int _arg, const char *_arg2, struct foo *_arg3,
                         struct bar *_arg4);
     static void      usage(void);

     /*
      * 全ての主要なルーチンはそれが何をするのかを簡潔に記述した
      * コメントを持つべきです。"main" ルーチンの前のコメントは
      * そのプログラムが何をするのかを記述するべきです。
      */
     int
     main(int argc, char *argv[])
                     case 'a':               /* case はインデントしない */
                             aflag = 1;
                             /* FALLTHROUGH */
                     case 'b':
                             bflag = 1;
                             break;
                     case 'n':
                             num = strtol(optarg, &ep, 10);
                             if (num <= 0 || *ep != '\0') {
                                     warnx("illegal number, -n argument -- %s",
                                         optarg);
                                     usage();
                             }
                             break;
                     case '?':
                     default:
                             usage();
                             /* NOTREACHED */
                     }
             argc -= optind;
             argv += optind;

     予約語 (if, while, for, return, switch) の後にスペースを入れます。何も伴
     わないかただ 1 つの文を伴う制御文は、ブレースを使用しません。 1 つの文が
     複数行である文の場合には、これは許されます。無限ループは while ではなく
     for で行ないます。

             for (p = buf; *p != '\0'; ++p)
                     ;       /* 何もなし */
             for (;;)
                     stmt;
             for (;;) {
                     z = a + really + long + statement + that + needs +
                         two lines + gets + indented + four + spaces +
                         on + the + second + and + subsequent + lines;
             }
             for (;;) {
                     if (cond)
                             stmt;
             }
             if (val != NULL)
                     val = realloc(val, newsize);

     for ループの各部は空のまま残しても構いません。異常に複雑なルーチンでない
     限りは、ブロックの中に宣言を置いてはなりません。

             for (; cnt < 15; cnt++) {
                     stmt1;
                     stmt2;
             }

     インデントは 8 文字のタブです。第 2 レベルのインデントは 4 文字のスペース

             if (test)
                     stmt;
             else if (bar) {
                     stmt;
                     stmt;
             } else
                     stmt;

     関数名の後はスペースを空けません。コンマの後にはスペースを持ちます。 `('
     または `[' の後ろまたは `]' または `)' の前にはスペースを空けません。

             error = function(a1, a2);
             if (error != 0)
                     exit(error);

     単項演算子はスペースを要求しませんが、二項演算子は要求します。優先順位が
     要求する場合または文が括弧なしでは混乱する場合以外は、括弧は使用しませ
     ん。他人はあなたよりも混乱しやすいかもしれないということを覚えておいてく
     ださい。あなたは以下を理解できますか?

             a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
             k = !(l & FLAGS);

     成功時には 0 で、または sysexits(3) にあらかじめ定義してある値で exit す
     るべきです。

             exit(EX_OK);    /*
                              * "Exit 0 on success." (成功時は 0 で終了)
                              * の様に明白なコメントは避けてください
                              */
     }

     関数の型は、関数自身に先行する行にあるべきです。

     static char *
     function(int a1, int a2, float fl, int a4)
     {

     関数の中で変数を宣言する時には、サイズ順に、次にアルファベット順にソート
     して宣言します。 1 行に複数の宣言は可能です。行が溢れる場合は、型の予約語
     を再度使用します。

     宣言時に変数を初期化することによってコードを不明瞭にしない様に注意してく
     ださい。この機能は良く考えて使用してください。初期化に関数呼び出しを使用
     しないでください。

             struct foo one, *two;
             double three;
             int *four, five;
             char *six, seven, eight, nine, ten, eleven, twelve;

     数にとって必須で、その他の引数にとっても必要です。) ポインタは NULL と比
     較します。例えば、

     !(p = f())

     ではなく、このように使います。

     (p = f()) == NULL

     真理値ではない場合、テストには '!' を使用しないでください。例えば、下記の
     ように使います。

     if (*p == '\0')

     下記のようには使いません。

     if (!*p)

     void * を返すルーチンでは、戻り値をどのポインタ型にもキャストしてはなりま
     せん。

     err(3) または warn(3) を使用し、勝手に作らないでください。

             if ((four = malloc(sizeof(struct foo))) == NULL)
                     err(1, (char *)NULL);
             if ((six = (int *)overflow()) == NULL)
                     errx(1, "number overflowed");
             return (eight);
     }

     古いスタイルの関数宣言はこのようになっています。

     static char *
     function(a1, a2, fl, a4)
             int a1, a2;     /* int 型も宣言します、デフォルトにしないこと */
             float fl;       /* double と float の違いに気を付けてください */
             int a4;         /* 出てきた順に宣言します */
     {

     あなたが明確に K&R との互換性を必要とする場合以外は、 ANSI の関数宣言を使
     用してください。長いパラメータリストの折り返しには、 4 個の空白による通常
     のインデントを付けます。

     可変個数の引数はこのようにします。

     #include <stdarg.h>

     void
     vaf(const char *fmt, ...)
     {
             va_list ap;

     使用法 (usage) の文はマニュアルページの書式の様であるべきです。使用法の文
     は、次の構造であるべきです:

     1.   オペランドの無いオプションが、最初にアルファベット順に、 1 組の大括
          弧 (`[' と `]') でくくられます。

     2.   オプションとそのオペランドがこれもアルファベット順に続き、それぞれの
          オプションとその引数を 1 組の大括弧でくくります。

     3.   必須の引数 (もしあれば) が続き、コマンドラインで指定されるべき順で一
          覧されます。

     4.   最後に、すべての任意の引数が指定されるべき順で、すべて大括弧の中に一
          覧されます。

     縦棒 (`|') は、二者択一のオプションまたは引数を分割し、同時に使用するオプ
     ションと引数は、単一の大括弧でくくります。

         "usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\n"
         "usage: f [-a | -b] [-c [-dEe] [-n number]]\n"

             (void)fprintf(stderr, "usage: f [-ab]\n");
             exit(EX_USAGE);
     }

     新しい中心的なカーネルのコードは、適度にスタイルガイドに従うべきです。サ
     ードパーティが保守するモジュールやデバイスドライバのためのガイドラインは
     より緩やかですが、最低限内部的には彼らの一貫したスタイルであるべきです。

     ソースリポジトリの文体の変更 (空白文字の変更を含む) は困難で、正当な理由
     なしには避けるべきです。リポジトリの中のおおよそ KNF style(9) に適合して
     いるコードは、この適合から離れてはなりません。

     可能な時にはいつでも、コードはコードチェッカ (例えば、 lint(1) または
     "gcc -Wall") を通過し、発生する警告は最小限となるべきです。


関連項目

     indent(1), lint(1), err(3), sysexits(3), warn(3)


歴史

     このページは 4.4BSD-Lite2 リリースの src/admin/style/style ファイルに大き
     く基づいていて、現在の実装と FreeBSD プロジェクトの要望を反映して、更新し
     てあります。

FreeBSD 4.4                    December 14, 1995                   FreeBSD 4.4

ABELNET VPSサービス