aboutsummaryrefslogtreecommitdiff
path: root/ja_JP.eucJP/man/man9/style.9
blob: a9f0f6d3fcf6707655e2216cae39461765472d92 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
.\" Copyright (c) 1995-2001 FreeBSD Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED.  IN NO EVENT SHALL [your name] OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" %FreeBSD: src/share/man/man9/style.9,v 1.101 2003/04/26 15:37:39 trhodes Exp %
.\" $FreeBSD$
.\"
.Dd December 7, 2001
.Dt STYLE 9
.Os
.Sh 名称
.Nm style
.Nd カーネルソースファイルのスタイルガイド
.Sh 解説
このファイルは
.Fx
ソースツリーのカーネルソースに好ましいスタイルを明記しています。
これはユーザランドのコードスタイルの手引きでもあります。
例において、スタイル規則の多くを暗黙的に使用しています。
.Nm
がこれらの事例について言及していないと決め付ける前に、
注意して例を確認してください。
.Nm
はそのような事柄については記述していません。
.\" $ と FreeBSD を続けるとキーワード置換されるので、\& を挿入
.\" 2001/05/23 horikawa@jp.FreeBSD.org
.Bd -literal
/*
 * FreeBSD のためのスタイルガイドです。
 * CSRG の KNF (Kernel Normal Form, カーネル標準書式) に基づいています。
 *
 *	@(#)style	1.14 (Berkeley) 4/28/95
 * $\&FreeBSD: src/share/man/man9/style.9,v 1.100 2003/03/25 19:46:55 jhb Exp $
 */

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

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

/*
 * 複数行にわたるコメントはこのようにします。実際の文章を書きます。実際の
 * 段落に見えるように埋めていきます。
 */
.Ed
.Pp
著作権ヘッダの後には空行を 1 行入れ、ソースファイルには
.Va rcsid
を付けます。
バージョン管理システムの ID タグは、ファイル中に 1 個のみあるべきです
(このファイルでは違いますが)。
C/C++ ソースファイル以外はこの例に従いますが、
C/C++ ソースファイルは以降の例に従います。
外部から入手したファイルの
すべての VCS (バージョン管理システム) リビジョン識別子は、
存在すれば維持します。
これには、ファイルの来歴を示す複数の ID も含みます。
一般的に、外来の ID またはその下部構造は編集しません。
さもなければ 
.Dq Li ( "#if defined(LIBC_SCCS)"
のように) 囲まれていない場合には、全ての互換性のない小片を隠すため、および
その ID をオブジェクトファイルから追い出しておくために、両方を
.Dq Li "#if 0 ... #endif"
の中に囲みます。
ファイルの名前が変更された場合には、外来の VCS ID の前に
.Dq Li "From: "
のみを追加します。
.Bd -literal
#if 0
#ifndef lint
static char sccsid[] = "@(#)style      1.14 (Berkeley) 4/28/95";
#endif /* not lint */
#endif

#include <sys/cdefs.h>
__FBSDID("$\&FreeBSD: src/share/man/man9/style.9,v 1.101 2003/04/26 15:37:39 trhodes Exp $");
.Ed
.Pp
ヘッダファイルの前に、空行を 1 行付けます。
.Pp
カーネルのインクルードファイル (すなわち、
.Pa sys/*.h
) が初めに来ます。
通常、
.Aq Pa sys/types.h
または
.Aq Pa sys/param.h
のどちらかが必要ですが、
両方は必要ないでしょう。
.Aq Pa sys/types.h
は
.Aq Pa sys/cdefs.h
をインクルードしており、
依存関係は問題ありません。
.Bd -literal
#include <sys/types.h>		/* 山括弧による非ローカルインクルード */
.Ed
.Pp
ネットワークプログラムである場合は、
次にネットワークインクルードファイルを置きます。
.Bd -literal
#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <netinet/in.h>
#include <protocols/rwhod.h>
.Ed
.Pp
カーネル用のファイルには、
.Pa /usr/include
中のファイルを使用しないでください。
.Pp
それから空行を置き、
.Pa /usr
インクルードファイルを続けます。
.Pa /usr
インクルードファイルはアルファベット順にソートされているべきです。
.Bd -literal
#include <stdio.h>
.Ed
.Pp
グローバルなパス名は
.Pa /usr/include/paths.h
で定義されています。
プログラムにローカルなパス名はローカルディレクトリの
.Qq Pa pathnames.h
に入れます。
.Bd -literal
#include <paths.h>
.Ed
.Pp
それから、空行があって、ユーザインクルードファイルが来ます。
.Bd -literal
#include "pathnames.h"		/* " " によるローカルインクルード */
.Ed
.Pp
アプリケーションインタフェースを実装している場合を除き、
実装の名前空間で
.Ic #define
したり名前を定義したりしてはいけません。
.Pp
.Dq Li 安全でない
マクロ (副作用を持っているもの) の名前と、
明らかな定数のマクロの名前はすべて大文字です。
式のように展開されるマクロは、単一のトークンにするか外側に括弧をつけます。
.Ic #define
とマクロ名の間にタブ文字を 1 個入れます。
マクロがある関数のインライン展開である場合は、
関数名は全て小文字で、マクロはすべて大文字の同じ名前を持ちます。
.\" XXX 上記は名前が同じマクロを #undef すれば関数を使える
.\" という ANSI のスタイルと衝突します。
.\" これは MALLOC() については言えないし、インライン関数を使う時の
.\" 一般的なやりかたではありません。
バックスラッシュは右揃えします。こうすると読みやすくなります。
マクロが複合文をカプセル化する場合には、それを
.Ic do
ループで囲みます。
これにより、
.Ic if
文で安全に使用できます。
最後の文の終端のセミコロンは、
マクロではなくマクロの実施時に付けられるべきです。
これにより、清書器やエディタで文法解析しやすくなります。
.Bd -literal
#define	MACRO(x, y) do {						\e
	variable = (x) + (y);						\e
	(y) += 2;							\e
} while (0)
.Ed
.Pp
コードが
.Ic #ifdef
または
.Ic #if
を使用して条件付きでコンパイルされるときには、
どこで条件付きでコンパイルされるコードが終了するのかを
読む人が容易に識別することが可能にするために、それに続く適合する
.Ic #endif
または
.Ic #else
にコメントを追加しても構いません。
このコメントは (主観的に) 長い部分、20 行以上の部分、またはネストされた
.Ic #ifdef
の連続が読む人を混乱させるかもしれないとき、にのみ使用されるべきです。
たとえコンパイルされない領域が小さくなるかもしれないでも、
.Xr lint 1
の目的のために条件付きでコンパイルされない個所のために、
例外が作られても構いません。
そのコメントは
.Ic #endif
または
.Ic #else
から 1 つの空白によって分離されるべきです。
短い条件付きでコンパイルされる部分のために、
終わりのコメントを使用するべきではありません。
.Pp
.Ic #endif
のためのコメントは対応する
.Ic #if
または
.Ic #ifdef
で使用されている表現に合わせるべきです。
.Ic #else
および
.Ic #elif
のためのコメントは先行する
.Ic #if
および/または
.Ic #elif
文に使用されている表現の反対に合わせるべきです。
コメントの中では、補助表現
.Dq Li defined(FOO)
は
.Dq Li FOO
と省略されます。
コメントの目的のためには、
.Dq Ic #ifndef Li FOO
は
.Dq Ic #if Li !defined(FOO)
とみなされます。
.Bd -literal
#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*/
.Ed
.Pp
列挙値は全て大文字を使用します。
.Bd -literal
enum enumtype { ONE, TWO } et;
.Ed
.Pp
宣言の中では、型に関係付けられたトークンを除いて、
アスタリスクと隣接したトークンの間には空白文字を置きません。
(これらの識別子は基本の型の名前、型の修飾語句、および今宣言されようとしている
もの以外の
.Ic typedef
名です。)
これらの識別子はアスタリスクから 1 つの空白で分離します。
.Pp
構造体の中で変数を宣言する時には、
使用順、サイズ順、アルファベット順にソートして宣言します。
最初の区分は通常適用しませんが、例外があります。
各宣言は、それぞれ独立した行にて行います。
構造体の名前の位置を、あなたの判断で読み易いように、
タブ 1 個または 2 個を使用して揃えてください。
少なくとも 90% のメンバの名前を揃えるのに十分な場合には、
1 つだけのタブを使用するべきです。
非常に長い型の後の名前は、単一の空白で区切られるべきです。
.Pp
重要な構造体は、それが使用されるファイルの先頭で宣言されるか、
複数のソースファイルで使用される場合は別のヘッダファイルで宣言されるべきです。
構造体がヘッダファイルで宣言されている場合には、
それら構造体の使用は、宣言とは分けられるべきで、かつ
.Ic "extern
であるべきです。
.Bd -literal
struct foo {
	struct foo	*next;		/* 使用中の foo のリスト */
	struct mumble	amumble;	/* mumble のコメント */
	int		bar;		/* コメントを揃えようとしています */
	struct verylongtypename *baz;	/* タブ 2 個には収まりません */
};
struct foo *foohead;			/* グローバルな foo リストの先頭 */
.Ed
.Pp
可能な時には必ず、あなた自身でリストを操作するのではなく、
.Xr queue 3
マクロを使用してください。
従って、前の例をより良く書くと次のようになります。
.Bd -literal
#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 リストの先頭 */
.Ed
.Pp
構造体の型に typedef を使用する事は避けてください。
使用してしまうと、
構造体へのポインタを不透明 (opaque) に使用することが、
アプリケーションにとって不可能となります。
通常の struct タグを使用すると、これが可能となり、かつ有益です。
規約が
.Ic typedef
を要求する場合には、その名前を構造体タグに一致させます。
標準 C または
.Tn POSIX
によって明示されたものを除いては、
.Dq Li _t
で終る typedef を避けてください。
.Bd -literal
/* 構造体名と typedef を一致させます */
typedef		struct bar {
	int	level;
} BAR;
typedef	int		foo;		/* これは foo です */
typedef	const long	baz;		/* これは baz です */
.Ed
.Pp
全ての関数はどこかでプロトタイプされます。
.Pp
私的な関数 (すなわち、他のどこでも使用されない関数など) の関数プロトタイプは、
最初のソースモジュールの先頭に置かれます。
単一のソースモジュールにローカルな関数は、
.Ic static
で宣言されるべきです。
.Pp
カーネルの別の部分から使用される関数は、
関連のあるインクルードファイルの中でプロトタイプされます。
関数プロトタイプは、異なる順序の使用を強制する理由がない場合には、
なるべくアルファベット順の論理的な順序で整列されるべきです。
.Pp
複数のモジュールでローカルに使用される関数は、
.Qq Pa extern.h
等の分離したヘッダファイルの中に置かれます。
.Pp
.Dv __P
マクロは使用しません。
.Pp
ファイルの 50% かそれ以上を巻き込んだ修正の場合は、
一般にコードは
.Dq 新しいコード
とみなすことができます。
これは既存のコードの慣例を破り、
現在の
.Nm
ガイドラインを使用するのに十分です。
.Pp
カーネルはパラメータの型に関連付けられた名前を持ちます。
例えば、カーネル内でこのように使用します。
.Bd -literal
void	function(int fd);
.Ed
.Pp
ユーザランドのアプリケーションに対して見えるヘッダファイルの中では、
可視のプロトタイプは、
型を伴った
.Dq 保護された
(アンダスコアで開始する) 名前を使用するか、
型だけで名前を使用しないかのどちらかが必要です。
保護された名前の使用がより望ましいです。
例えば、このように使用します。
.Bd -literal
void	function(int);
.Ed
.Pp
または
.Bd -literal
void	function(int _fd);
.Ed
.Pp
プロトタイプは関数名の行揃えを行なうために、タブの後に追加のスペース文字を
置いても構いません。
.Bd -literal
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;
.Ed
.Pp
一貫性のために、オプションの解析には
.Xr getopt 3
が使用されるべきです。
.Xr getopt 3
呼び出しと
.Ic switch
文では、オプションをソートすべきですが、
.Ic switch
文のカスケードの一部の場合は例外です。
.Ic switch
文のカスケード要素は
.Li FALLTHROUGH
コメントを持つべきです。
数値の引数は精度をチェックされるべきです。
到達できないコードは
.Li NOTREACHED
コメントを持つべきです。
.Bd -literal
	while ((ch = getopt(argc, argv, "abn:")) != -1)
		switch (ch) {		/* switch をインデント */
		case 'a':		/* case はインデントしない */
			aflag = 1;
			/* FALLTHROUGH */
		case 'b':
			bflag = 1;
			break;
		case 'n':
			num = strtol(optarg, &ep, 10);
			if (num <= 0 || *ep != '\e0') {
				warnx("illegal number, -n argument -- %s",
				    optarg);
				usage();
			}
			break;
		case '?':
		default:
			usage();
			/* NOTREACHED */
		}
	argc -= optind;
	argv += optind;
.Ed
.Pp
予約語
.Pq Ic if , while , for , return , switch
の後にスペースを入れます。
何も伴わないか、ただ 1 つの文を伴う制御文は、ブレース
.Ql ( \&{
および
.Ql \&} )
を使用しません。
1 つの文が 複数行である文の場合には、これは許されます。
無限ループは
.Ic while
ではなく
.Ic for
で行ないます。
.Bd -literal
	for (p = buf; *p != '\e0'; ++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);
.Ed
.Pp
.Ic for
ループの各部は空のまま残しても構いません。
異常に複雑なルーチンでない限りは、ブロックの中に宣言を置いてはなりません。
.Bd -literal
	for (; cnt < 15; cnt++) {
		stmt1;
		stmt2;
	}
.Ed
.Pp
インデントは 8 文字のタブです。
第 2 レベルのインデントは 4 文字のスペースです。
長い分を折り返す必要がある場合、オペレータを行末に置きます。
.Bd -literal
	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;
.Ed
.Pp
空白文字を行末に追加してはいけません。
また、インデントを形成するためには、タブとその後にスペースのみを使用します。
タブが生み出す以上のスペースや、タブの前のスペースは使用しません。
.Pp
ブレースの終了と開始は
.Ic else
と同じ行に置かれます。
必要でないブレースは省いても構いません。
.Bd -literal
	if (test)
		stmt;
	else if (bar) {
		stmt;
		stmt;
	} else
		stmt;
.Ed
.Pp
関数名の後はスペースを空けません。
コンマの後にはスペースを持ちます。
.Ql \&(
または
.Ql \&[
の後ろまたは
.Ql \&]
または
.Ql \&)
の前にはスペースを空けません。
.Bd -literal
	error = function(a1, a2);
	if (error != 0)
		exit(error);
.Ed
.Pp
単項演算子はスペースを要求しませんが、二項演算子は要求します。
優先順位が要求する場合または文が括弧なしでは混乱する場合以外は、
括弧は使用しません。
他人はあなたよりも混乱しやすいかもしれないということを覚えておいてください。
あなたは以下を理解できますか?
.Bd -literal
	a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
	k = !(l & FLAGS);
.Ed
.Pp
成功時には 0 で、または
.Xr sysexits 3
にあらかじめ定義してある値で exit するべきです。
.Bd -literal
	exit(EX_OK);	/*
			 * "Exit 0 on success." (成功時は 0 で終了)
			 * の様に明白なコメントは避けてください
			 */
}
.Ed
.Pp
関数の型は、関数自身に先行する行にあるべきです。
関数の本体の開始のブレースは、単独で 1 行であるべきです。
.Bd -literal
static char *
function(int a1, int a2, float fl, int a4)
{
.Ed
.Pp
関数の中で変数を宣言する時には、サイズ順に、次にアルファベット順に
ソートして宣言します。
1 行に複数の宣言は可能です。
行が溢れる場合は、型の予約語を再度使用します。
.Pp
宣言時に変数を初期化することによってコードを
不明瞭にしない様に注意してください。
この機能は良く考えて使用してください。
初期化に関数呼び出しを使用しないでください。
.Bd -literal
	struct foo one, *two;
	double three;
	int *four, five;
	char *six, seven, eight, nine, ten, eleven, twelve;

	four = myfunction();
.Ed
.Pp
他の関数の内部で関数を宣言しないでください。
ANSI C によると、このような宣言は、宣言のネスティングによらず、
ファイルスコープになります。
ローカルスコープに見えるものの中にファイルの宣言を隠すことは好ましくなく、
良いコンパイラは苦情を言います。
.Pp
キャストと
.Ic sizeof
演算子の後にはスペースを続けません。
この規則は
.Xr indent 1
が理解しないことに注意してください。
.Ic sizeof
は常に括弧をつけて書かれます。
冗長な括弧の規則は
.Fn sizeof var
の事例には適用されません。
.Pp
.Dv NULL
は、好まれるヌルポインタ定数です。
コンパイラが型を知っている文脈、例えば代入では、
.Vt ( "type *" ) Ns 0
または
.Vt ( "type *" ) Ns Dv NULL
の代わりに、
.Dv NULL
を使用します。
他の文脈では、特に全ての関数の引数では、
.Vt ( "type *" ) Ns Dv NULL
を使用します。
(関数のプロトタイプがスコープ外かもしれない場合に、
キャストはいろいろな引数にとって必須で、その他の引数にとっても必要です。)
ポインタは
.Dv NULL
と比較します。例えば、
.Bd -literal
!(p = f())
.Ed
.Pp
ではなく、このように使います。
.Bd -literal
(p = f()) == NULL
.Ed
.Pp
真理値ではない場合、テストには
.Ic \&!
を使用しないでください。
例えば、下記のように使います。
.Bd -literal
if (*p == '\e0')
.Ed
.Pp
下記のようには使いません。
.Bd -literal
if (!*p)
.Ed
.Pp
.Vt "void *"
を返すルーチンでは、
戻り値をどのポインタ型にもキャストしてはなりません。
.Pp
.Ic return
文の値は括弧で囲まれているべきです。
.Pp
.Xr err 3
または
.Xr warn 3
を使用し、勝手に作らないでください。
.Bd -literal
	if ((four = malloc(sizeof(struct foo))) == NULL)
		err(1, (char *)NULL);
	if ((six = (int *)overflow()) == NULL)
		errx(1, "number overflowed");
	return (eight);
}
.Ed
.Pp
古いスタイルの関数宣言はこのようになっています。
.Bd -literal
static char *
function(a1, a2, fl, a4)
	int a1, a2;	/* int 型も宣言します、デフォルトにしないこと */
	float fl;	/* double と float の違いに気を付けてください */
	int a4;		/* 出てきた順に宣言します */
{
.Ed
.Pp
あなたが明確に K&R との互換性を必要とする場合以外は、
ANSI の関数宣言を使用してください。
長いパラメータリストの折り返しには、
4 個の空白による通常のインデントを付けます。
.Pp
可変個数の引数はこのようにします。
.Bd -literal
#include <stdarg.h>

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

	va_start(ap, fmt);
	STUFF;
	va_end(ap);
	/* void 型の関数に return は不要です */
}

static void
usage()
{
	/* 関数がローカル変数を持たない場合、空行をいれます */
.Ed
.Pp
.Xr fputs 3 ,
.Xr puts 3 ,
.Xr putchar 3
等ではなく、
.Xr printf 3
を使用してください。
これは速くて大抵はきれいで、言うまでもなくつまらないバグを避けます。
.Pp
使用法 (usage) の文はマニュアルページの
.Sx SYNOPSIS
(書式) の様であるべきです。
使用法の文は、次の構造であるべきです:
.Bl -enum
.It
オペランドの無いオプションが、最初にアルファベット順に、
1 組の大括弧
.Ql ( \&[
と
.Ql \&] )
でくくられます。
.It
オプションとそのオペランドがこれもアルファベット順に続き、
それぞれのオプションとその引数を 1 組の大括弧でくくります。
.It
必須の引数
(もしあれば)
が続き、
コマンドラインで指定されるべき順で一覧されます。
.It
最後に、
すべての任意の引数が指定されるべき順で、
すべて大括弧の中に一覧されます。
.El
.Pp
縦棒
.Pq Ql \&|
は、
.Dq 二者択一
のオプションまたは引数を分割し、
同時に使用するオプションと引数は、単一の大括弧でくくります。
.Bd -literal -offset 4n
"usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\en"
"usage: f [-a | -b] [-c [-dEe] [-n number]]\en"
.Ed
.Bd -literal
	(void)fprintf(stderr, "usage: f [-ab]\en");
	exit(EX_USAGE);
}
.Ed
.Pp
マニュアルページのオプション記述は、
純粋なアルファベット順であるべきであることに注意してください。
つまり、オプションが引数を取るか否かに関わらないということです。
アルファベット順は、前述の大文字小文字の順序を考慮に入れるべきです。
.Pp
新しい中心的なカーネルのコードは、適度に
.Nm
ガイドに従うべきです。
サードパーティが保守するモジュールやデバイスドライバのためのガイドラインは
より緩やかですが、最低限内部的には彼らの一貫したスタイルであるべきです。
.Pp
ソースリポジトリの文体の変更 (空白文字の変更を含む) は困難で、
正当な理由なしには避けるべきです。
リポジトリの中のおおよそ
KNF
.Nm
に適合しているコードは、この適合から離れてはなりません。
.Pp
可能な時にはいつでも、
コードはコードチェッカ (例えば、
.Xr lint 1
または
.Nm gcc Fl Wall
) を
通過し、発生する警告は最小限となるべきです。
.Sh 関連項目
.Xr indent 1 ,
.Xr lint 1 ,
.Xr err 3 ,
.Xr sysexits 3 ,
.Xr warn 3 ,
.Xr style.Makefile 5
.Sh 歴史
このページは
.Bx 4.4 Lite2
リリースの
.Pa src/admin/style/style
ファイルに大きく基づいていて、
現在の実装と
.Fx
プロジェクトの要望を反映して、頻繁に更新しています。