日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.4-RELEASE-K, 13.0-RELEASE-K から 13.3-RELEASE-K, 14.0-RELEASE-K から 14.1-RELEASE-K は、全翻訳済み)
13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。
Table of Contents
STYLE(9) FreeBSD カーネル開発者マニュアル STYLE(9) 名称 style -- カーネルソースファイルのスタイルガイド 解説 このファイルは、FreeBSD ソースツリーのカーネルのソースファイルのための好 ましいスタイルを述べています。また、それは、好ましいユーザランドのコード スタイルのためのガイドです。スタイル規則の多くは、使用例で暗黙的です。 style が問題について沈黙していると仮定する前に使用例をチェックするように 注意してください。 /* * FreeBSD のためのスタイルガイド. CSRG の KNF (Kernel Normal Form) * に基づいている. * * @(#)style 1.14 (Berkeley) 4/28/95 * $FreeBSD: release/11.4.0/share/man/man9/style.9 291861 2015-12-05 17:01:38Z cem $ */ /* * 非常に重要な 1 行コメントは, このようになります. */ /* ほとんどの単一行コメントは, このようになります. */ /* * 複数行のコメントは, このようになります. それらを実際のセンテンスに * します. それらが実際のパラグラフのように見えるように, それらを満た * します. */ 著作権のヘッダは、次のように星の後にダッシュがあるコメントの最初の行があ る、複数行のコメントであるべきです: /*- * Copyright (c) 1984-2025 John Q. Public * All rights reserved. * * 長くて, 退屈なライセンスは, ここですが, 簡潔さのために切り詰めました. */ 自動スクリプトは、最初のカラムが ``/*-'' で始まるすべてのコメントのための ツリーからライセンス情報を集めます。ライセンスまたは著作権表示でない最初 のカラムで始まるコメントを再書式化しないために indent(1) を停止させたいな ら、それらのコメントに対してダッシュを星に変更します。最初以外のカラムで 始まるコメントは、ライセンス声明と見なされません。 あらゆる著作権のヘッダの後に、空行と C/C++ 言語でないソースファイルのため に $FreeBSD$ があります。バージョン管理システム ID タグは、(このファイル では違っていますが) ファイルに 1 つだけ存在するべきです。C/C++ でないソー スファイルは、上記の例に従いますが、C/C++ ソースファイルは、下記のものに 従います。他の場所から取得されたファイルの VCS (バージョン管理システム) リビジョン識別は、適応可能なところで、ファイルの歴史を示す複数の ID を含 めて、維持されるべきです。一般的に、外来の ID またはそれらの構造基盤を編 集しません。(``#if defined(LIBC_SCCS)'' のように) 特に他のラップされたも のがないなら、あらゆるコンパイル可能でない部分を隠すために、そしてオブ ジェクトファイルの ID 出力を保持するために、``#if 0 ... #endif'' の両方で 囲みます。ファイルの名前が変更されるなら、外来の VCS ID の前に ``From: '' のみを追加します。 #if 0 #ifndef lint static char sccsid[] = "@(#)style 1.14 (Berkeley) 4/28/95"; #endif /* not lint */ #endif #include <sys/cdefs.h> __FBSDID("$FreeBSD: release/11.4.0/share/man/man9/style.9 291861 2015-12-05 17:01:38Z cem $"); ヘッダファイルの前に別の空行を残します。 カーネルのインクルードファイル (すなわち、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 <net/route.h> #include <netinet/in.h> #include <protocols/rwhod.h> カーネルのファイルのために /usr/include 中のファイルを使用してはいけませ ん。 名前によってアルファベット順にソートされるべきである、次のグループ、 /usr/include ファイルの前に、空行を残します。 #include <stdio.h> グローバルなパス名は、<paths.h> に定義されています。プログラムにローカル なパス名は、ローカルディレクトリの "pathnames.h" に入ります。 #include <paths.h> ユーザのインクルードファイルの前に、別の空行を残します。 #include "pathnames.h" /* 二重引用符中のローカルなインクルード. */ アプリケーションのインタフェースを実装することを除いて、実装の名前空間で #define または名前を宣言してはけません。 ``unsafe'' マクロ (副作用があるもの) の名前と明白な定数のためのマクロの名 前は、すべて大文字です。式のようなマクロの展開は、単一のトークン、または 外側に括弧があるかのいずれかです。#define とマクロの名前の間に単一のタブ 文字を置きます。マクロが関数のインライン展開であるなら、関数名は、すべて 小文字で、マクロには、すべて大文字の同じ名前があります。バックスラッシュ を右揃えにします。それは、読むことをより簡単にします。マクロが複合文をカ プセル化するなら、do ループでそれを囲んで、つまり、それは、安全に if 文で 使用することができます。あらゆる最後の文を終了するセミコロンは、きれいな プリンタとエディタのために解析をより簡単にするために、マクロではなくマク ロの呼び出しによって供給されるべきです。 #define MACRO(x, y) do { \ variable = (x) + (y); \ (y) += 2; \ } while (0) コードが #ifdef または #if を使用して条件付きでコンパイルされるとき、コメ ントは、条件付きでコンパイルされたコードの範囲がどこで終了するか、読み手 が容易に識別することを可能にするために一致する #endif または #else に続い て追加されます。このコメントは、20 行の以上の領域の長い領域のだめだけ、ま たはひと続きの入れ子になった #ifdef が、読み手に混乱されないところでのみ (主観的に) 使用されるべきです。例外は、たとえコンパイルされている範囲が小 いさくても、コードが lint(1) の目的のために条件付きでコンパイルされない場 合に認められます。コメントは、1 つの空白によって #endif または #else と分 離されるべきです。短い条件付きでコンパイルされた範囲について、コメントの 終りは、使用されるべきではありません。 #endif のためのコメントは、対応する #if または #ifdef で使用される式と一 致するべきです。#else と #elif のためのコメントは、以前の #if および #elif 文で使用される (複数の) 式の反対と一致するべきです。コメントの中 で、部分式 ``defined(FOO)'' は、``FOO'' と短縮されます。コメントの目的た めに、``#ifndef FOO'' は、``#if !defined(FOO)'' として扱われます。 #ifdef KTRACE #include <sys/ktrace.h> #endif #ifdef COMPAT_43 /* 大きな範囲はここ, または他の条件付きのコード. */ #else /* !COMPAT_43 */ /* またはここ. */ #endif /* COMPAT_43 */ #ifndef COMPAT_43 /* もう一つの大きな範囲はここ, または他の条件付きのコード. */ #else /* COMPAT_43 */ /* またはここ. */ #endif /* !COMPAT_43 */ プロジェクトは、形式 u_intXX_t の古い BSD スタイルの整数識別子に優先して 形式 uintXX_t の ISO/IEC 9899:1999 (``ISO C99'') 符号なし整数識別子を使用 するように徐々に移行しています。新しいコードは、前者を使用するべきで、他 の主な作業がその領域で行われており、より古い BSD スタイルを選ぶ決定的な理 由をないなら、古いコードは、新しい形式に変換されるべきです。空白類のコ ミットのように、uintXX_t のみのコミットを行う際に注意するべきです。 同様に、プロジェクトは、古い int または boolean_t に優先して、ISO/IEC 9899:1999 (``ISO C99'') bool を使用するためにゆっくり動いています。新しい コードは、bool を使用するべきで、古いコードは、それが、そうすることが妥当 であるなら、変換されます。リテラル値は、true と false と名前が付けられま す。これらは、古いスペルの TRUE と FALSE より好まれます。ユーザ空間のコー ドは、<stdbool.h> を含むべきで、一方、カーネルコードは、<sys/types.h> を 含むべきです。 列挙型の値は、すべて大文字です。 enum enumtype { ONE, TWO } et; 識別子の internal_underscores の使用は、camelCase または TitleCase より優 先されます。 宣言において、タイプと関連する識別子であるトークンを除いて、アスタリスク (星) と隣接したトークンの間に、何も空白類を置きません。(これらの識別子 は、基本のタイプの名前、タイプの修飾子、と宣言されているもの以外の typedef 名です。) 1 つの空白を使用して、アスタリスクから、これらの識別子 を分離します。 構造体中の変数を宣言するとき、使用順、次にサイズ順 (大きなものから小さな ものに)、次に、アルファベット順にソートされたものを宣言します。最初のカテ ゴリは、通常適用されませんが、例外があります。各々は、それ自体の行で行い ます。利用者の判断に依存して、1 つまたは 2 つのタブを使用して、メンバ名を 整列させることによって、構造体を読みやすくしようと試みます。メンバ名の少 なくとも 90% を整列させるために十分である場合のみ、1 つのタブを使用するべ きです。非常に長いタイプに続く名前は、単一の空白によって区切られるべきで す。 主要な構造体は、それらが使用されるファイルの先頭で宣言されるか、または、 それらが複数のソースファイルで使用されるなら、個別のヘッダファイルで宣言 されるべきです。構造体の使用は、個別の宣言によるべきであり、それらがヘッ ダファイルで宣言されるなら、extern であるべきです。 struct foo { struct foo *next; /* アクティブな foo のリスト. */ struct mumble amumble; /* mumble のコメント. */ int bar; /* コメントを整列しようとする. */ struct verylongtypename *baz; /* 2 つのタブに, 合わない. */ }; struct foo *foohead; /* グローバルな foo リストの先頭. */ 指定できるときはいつでも、利用者自身のリストを繰り返すことではなく queue(3) マクロを使用します。したがって、以前の使用例は、次のように、より 良く書かれるでしょう: #include <sys/queue.h> struct foo { LIST_ENTRY(foo) link; /* foo リストのキューマクロを 使用する. */ struct mumble amumble; /* mumble のコメント. */ int bar; /* コメントを揃えます. */ struct verylongtypename *baz; /* 2 つのタブに, 合わない. */ }; LIST_HEAD(, foo) foohead; /* グローバルな foo リストの先頭. */ 構造体のタイプのための typedef の使用を避けます。typedef は、それらの基本 的なタイプを適切に隠さないので、問題があります。例えば、typedef が構造体 自体であるか、または構造体へのポインタであるかどうか知る必要があります。 さらに、それらは、正確に一度宣言されなければなりませんが、必要に応じて何 度でも不完全な構造体のタイプを宣言することができます。typedef は、スタン ドアロンのヘッダファイルで使用することは困難です: typedef を定義するヘッ ダは、それを使用するヘッダの前に、または (名前空間の汚染を引き起こす) そ れを使用するヘッダの前に、インクルードされなければなりません、または typedef を取得するための裏口 (back-door) メカニズムがなければなりません。 規約が typedef を要求するとき、その名前を構造体のタグと一致させます。標準 C または POSIX によって明記されたものを除いて、``_t'' で終る typedef を避 けてください。 /* 構造体名と typedef を一致させる. */ typedef struct bar { int level; } BAR; typedef int foo; /* これは, foo です. */ typedef const long baz; /* これは, baz です. */ すべての関数は、どこかでプロトタイプ宣言されます。 プライベート関数 (すなわち、他のところで使用されない関数) のための関数プ ロトタイプは、最初のソースモジュールの先頭に置かれます。1 つのソースモ ジュールにローカルである関数は、static と宣言されるべきです。 カーネルの他の部分から使用される関数は、関連するインクルードファイルでプ ロトタイプ宣言されます。関数プロトタイプは、異なった順序を使用するやむを 得ない理由がないなら、なるべくアルファベット順の論理的順序でリストされる べきです。 2 つ以上のモジュールでローカルに使用される関数は、個別のヘッダファイル、 例えば、"extern.h" に置かれます。 __P マクロを使用しません。 一般的に、含まれていた (複数の) ファイルの約 50% 以上を作成するとき、コー ドは、``新しいコード'' とみなすことができます。これは、既存のコードで前例 を破り、現在の style ガイドラインを使用するのに十分です。 カーネルは、パラメータのタイプに関連した名前があります、例えば、カーネル で、次のように使用します: 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[]) { char *ep; long num; int ch; 一貫性を保つために、getopt(3) は、オプションを解析するために使用されるべ きです。switch の部分がカスケードでないなら、オプションは、getopt(3) 呼び 出しと switch 文でソートされるべきです。カスケードされた switch 文の要素 は、FALLTHROUGH コメントがあるべきです。数値の引数は、精度をチェックされ るべきです。明白でない理由のために到達されないコードは、/* NOTREACHED */ とマークされます。 while ((ch = getopt(argc, argv, "abNn:")) != -1) switch (ch) { /* switch をインデント. */ case 'a': /* case をインデントしない. */ aflag = 1; /* case の本体を 1 つのタブで インデント. */ /* FALLTHROUGH */ case 'b': bflag = 1; break; case 'N': Nflag = 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(); } argc -= optind; argv += optind; キーワード (if, while, for, return, switch) の後の空白。大括弧 (ブレース) (`{' と `}') の 2 つのスタイルは、単一の行の文を許可します。それらが、す べての単一の文のために使用されるか、またはそれらが、明確さのために必要と されるところでのみ使用されるかのいずれかです。関数内の使用法は、一貫性が あるべきです。永久ループは、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 つの空白です。長い文を折り畳まなければならないなら、 行の終わりにオペレータを置きます。 while (cnt < 20 && this_variable_name_is_too_long && ep != NULL) z = a + really + long + statement + that + needs + two + lines + gets + indented + four + spaces + on + the + second + and + subsequent + lines; 行の終わりに空白類を追加しなでください、インデンテーションを形成するため には、空白が続くタブだけを使用します。タブが生成するより多くの空白を使用 しないでください、そしてタブの前に空白を使用しなでください。 閉大括弧 (閉ブレース) と開大括弧 (開ブレース) は、else と同じ行に置きま す。必要でない大括弧 (ブレース) は、省略されます。 if (test) stmt; else if (bar) { stmt; stmt; } else stmt; 関数名の後に空白を空けません。コンマは、それらの後ろに空白があります。`(' または `[' の後ろ、そして `]' または `)' の前に、空白を空けません。 error = function(a1, a2); if (error != 0) exit(error); 単項演算子は、空白を必要としません、2 項演算子は、必要とします。それらが 優先順序のために必要でないなら、または文がそれらなしで混乱されないなら、 括弧を使用しません。他の人々は、利用者より容易に混同するかもしれないこと を覚えておいてください。「利用者」は、下記を理解できますか? a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1; k = !(l & FLAGS); 成功すれば、0 で終了するべきで、失敗すれば、1 で終了するべきです。 exit(0); /* * "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; four = myfunction(); 他の関数の内部で関数を宣言しないでください。そのような宣言には、宣言のネ スティングにかかわらずファイルスコープがあると、ANSI C は、記述していま す。ローカルスコープにあるように思われるものの中のファイル宣言を隠すこと は、望ましくなく、よいコンパイラからエラーを顕在化します。 キャストと sizeof は、空白が続きません。indent(1) は、この規則を理解しな いことに注意してください。sizeof は、常に、括弧をつけて書かれます。冗長な 括弧の規則は、sizeof(var) の事例に適用されません。 NULL は、好ましい null ポインタの定数です。例えば、代入で、コンパイラがタ イプを知っているコンテキストで、(type *)0 または (type *)NULL の代わりに NULL を使用します。特にすべての関数の引数では、他のコンテキストで (type *)NULL を使用します。(キャストは、可変個引数のために不可欠で、関数のプロ トタイプがスコープにないなら、他の引数のために必要です。) NULL に対するポ インタのテストは、例えば、次のように使用します: 例えば、次のように使用し ます: (p = f()) == NULL 次のように使用しません: !(p = f()) ブール値ではないなら、テストのために ! を使用しません。例えば、次のように 使用します: if (*p == '\0') 次のように使用しません: if (!*p) void * を返すルーチンは、それらの返り値をあらゆるポインタのタイプにキャス トさせるべきではありません。 return 文の値は、括弧で囲まれるべきです。 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; va_start(ap, fmt); STUFF; va_end(ap); /* void の関数に return は不要. */ } static void usage() { /* 関数にローカル変数がないなら, 空行を挿入. */ fputs(3), puts(3), putchar(3) のようなものは何でも、printf(3) を使用して ください。それは、愚かなバグの回避は言うまでもなく、より速く、通常よりク リーンです。 使用法の文は、マニュアルページの「書式」らしくあるべきです。使用法の文 は、次の順序で構築されるべきです: 1. オペランドのないオプションは、1 組の大括弧 (`[' と `]') の内側で、ア ルファベット順に、最初に出現します。 2. オペランドがあるオプションは、それ自体の組の角括弧 (ブラケット) の内 側の各オプションとその引数とともに、アルファベット順で次に出現しま す。 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(1); } マニュアルページのオプションの記述は、純粋なアルファベット順のオプション をリストするべきであることに注意してください。すなわち、オプションが引数 を取るかどうかに関係ないということです。アルファベットの順序は、上記に示 されている順序の場合を考慮に入れるべきです。 新しい中心のカーネルコードは、style ガイドに無理なく準拠するべきです。 サードパーティのためのガイドラインは、モジュールを維持し、デバイスドライ バは、より緩やかですが、最低限、それらのスタイルと内部的に一貫しているべ きです。 文体の変更 (空白類の変更を含む) は、ソースリポジトリに対して厳しく、これ といった理由なしには避けなければなりません。ほぼリポジトリに準拠している FreeBSD KNF style であるコードは、準拠と異なってはいけません。 可能なときはいつでも、コードは、コードチェッカ (例えば、lint(1) または cc -Wall) を通して実行されるべきで、最小の警告を生成するべきです。 関連項目 indent(1), lint(1), err(3), warn(3), style.Makefile(5) 歴史 このマニュアルページは、FreeBSD プロジェクトの現在の慣習と要望を反映する ための時折の更新を伴って、4.4BSD-Lite2 リリースの src/admin/style/style ファイルに大部分基づいています。src/admin/style/style は、Version 6 AT&T UNIX の Ken Thompson と Dennis Ritchie のプログラミングスタイルを CSRG に よって成文化したものです。 FreeBSD 11.4 December 5, 2015 FreeBSD 11.4