style(9)
NAME
style - kernel source file style guide
DESCRIPTION
- This file specifies the preferred style for kernel source
- files in the
FreeBSD source tree. It is also a guide for the preferred - userland code
style. Many of the style rules are implicit in the exam - ples. Be careful
to check the examples before assuming that style is silent - on an issue.
- /*
- * Style guide for FreeBSD. Based on the CSRG's KNF (Kernel
- Normal Form).
*
* @(#)style 1.14 (Berkeley) 4/28/95
* $FreeBSD: src/share/man/man9/style.9,v 1.121 2005/06/28 - 20:15:18 hmp Exp $
*/ - /*
- * VERY important single-line comments look like this.
*/ - /* Most single-line comments look like this. */
- /*
- * Multi-line comments look like this. Make them real sen
- tences. Fill
* them so they look like real paragraphs.
*/ - The copyright header should be a multi-line comment, with
- the first line
of the comment having a dash after the star like so: - /*
- * Copyright (c) 1984-2025 John Q. Public. All Rights Re
- served.
*
* Long, boring license goes here, but redacted for brevity
*/ - An automatic script collects license information from the
- tree for all
comments that start in the first column with ``/*-''. If - you desire to
flag indent(1) to not reformat a comment that starts in the - first column
which is not a license or copyright notice, change the dash - to a star for
those comments. Comments starting in columns other than the - first are
never considered license statements. - After any copyright header, there is a blank line, and the
- $FreeBSD$ for
non C/C++ language source files. Version control system ID - tags should
only exist once in a file (unlike in this one). Non-C/C++ - source files
follow the example above, while C/C++ source files follow - the one below.
All VCS (version control system) revision identification in - files
obtained from elsewhere should be maintained, including, - where applicable, multiple IDs showing a file's history. In general, do
- not edit foreign IDs or their infrastructure. Unless otherwise wrapped
- (such as
``#if defined(LIBC_SCCS)''), enclose both in ``#if 0 ... - #endif'' to hide
any uncompilable bits and to keep the IDs out of object - files. Only add
``From: '' in front of foreign VCS IDs if the file is re - named.
- #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.121 - 2005/06/28 20:15:18 hmp Exp $");
- Leave another blank line before the header files.
- Kernel include files (i.e. sys/*.h) come first; normally,
- include
#include <sys/types.h>
OR but not both. #include <sys/types.h> includes and it is okay to depend on that. - #include <sys/types.h> /* Non-local includes in angle
- brackets. */
- For a network program, put the network include files next.
- #include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <netinet/in.h>
#include <protocols/rwhod.h> - Do not use files in /usr/include for files in the kernel.
- Leave a blank line before the next group, the /usr/include
- files, which
should be sorted alphabetically by name. - #include <stdio.h>
- Global pathnames are defined in Pathnames local to the pro
- gram go in
"pathnames.h" in the local directory. - #include <paths.h>
- Leave another blank line before the user include files.
- #include "pathnames.h" /* Local includes in double
- quotes. */
- Do not #define or declare names in the implementation names
- pace except
for implementing application interfaces. - The names of ``unsafe'' macros (ones that have side ef
- fects), and the
names of macros for manifest constants, are all in upper - case. The expansions of expression-like macros are either a single token or
- have outer
parentheses. Put a single tab character between the #define - and the
macro name. If a macro is an inline expansion of a func - tion, the function name is all in lowercase and the macro has the same
- name all in
uppercase. Right-justify the backslashes; it makes it easi - er to read.
If the macro encapsulates a compound statement, enclose it - in a do loop,
so that it can safely be used in if statements. Any final - statement-terminating semicolon should be supplied by the macro invoca
- tion rather than
the macro, to make parsing easier for pretty-printers and - editors.
- #define MACRO(x, y) do {
- variable = (x) + (y);
- (y) += 2;
- } while (0)
- When code is conditionally compiled using #ifdef or #if, a
- comment may be
added following the matching #endif or #else to permit the - reader to easily discern where conditionally compiled code regions end.
- This comment
should be used only for (subjectively) long regions, regions - greater than
20 lines, or where a series of nested #ifdef 's may be con - fusing to the
reader. Exceptions may be made for cases where code is con - ditionally not
compiled for the purposes of lint(1), even though the uncom - piled region
may be small. The comment should be separated from the - #endif or #else
by a single space. For short conditionally compiled re - gions, a closing
comment should not be used. - The comment for #endif should match the expression used in
- the corresponding #if or #ifdef. The comment for #else and #elif
- should match the
inverse of the expression(s) used in the preceding #if - and/or #elif
statements. In the comments, the subexpression ``de - fined(FOO)'' is
abbreviated as ``FOO''. For the purposes of comments, - ``#ifndef FOO'' is
treated as ``#if !defined(FOO)''. - #ifdef KTRACE
#include <sys/ktrace.h>
#endif - #ifdef COMPAT_43
/* A large region here, or other conditional code. */
#else /* !COMPAT_43 */
/* Or here. */
#endif /* COMPAT_43 */ - #ifndef COMPAT_43
/* Yet another large region here, or other conditional code. - */
#else /* COMPAT_43 */
/* Or here. */
#endif /* !COMPAT_43 */ - The project is slowly moving to use the ISO/IEC 9899:1999
- (``ISO C99'')
unsigned integer identifiers of the form uintXX_t in prefer - ence to the
older BSD-style integer identifiers of the form u_intXX_t. - New code
should use the former, and old code should be converted to - the new form
if other major work is being done in that area and there is - no overriding
reason to prefer the older BSD-style. Like white-space com - mits, care
should be taken in making uintXX_t only commits. - Enumeration values are all uppercase.
- enum enumtype { ONE, TWO } et;
- In declarations, do not put any whitespace between asterisks
- and adjacent
tokens, except for tokens that are identifiers related to - types. (These
identifiers are the names of basic types, type qualifiers, - and
typedef-names other than the one being declared.) Separate - these identifiers from asterisks using a single space.
- When declaring variables in structures, declare them sorted
- by use, then
by size (largest to smallest), and then in alphabetical or - der. The first
category normally does not apply, but there are exceptions. - Each one
gets its own line. Try to make the structure readable by - aligning the
member names using either one or two tabs depending upon - your judgment.
You should use one tab only if it suffices to align at least - 90% of the
member names. Names following extremely long types should - be separated
by a single space. - Major structures should be declared at the top of the file
- in which they
are used, or in separate header files if they are used in - multiple source
files. Use of the structures should be by separate declara - tions and
should be extern if they are declared in a header file. - struct foo {
- struct foo *next; /* List of active
- foo. */
struct mumble amumble; /* Comment for mum - ble. */
int bar; /* Try to align the - comments. */
struct verylongtypename *baz; /* Won't fit in 2 - tabs. */
- };
struct foo *foohead; /* Head of global - foo list. */
- Use queue(3) macros rather than rolling your own lists,
- whenever possible. Thus, the previous example would be better written:
- #include <sys/queue.h>
- struct foo {
- LIST_ENTRY(foo) link; /* Use queue macros
- for foo lists. */
struct mumble amumble; /* Comment for mum - ble. */
int bar; /* Try to align the - comments. */
struct verylongtypename *baz; /* Won't fit in 2 - tabs. */
- };
LIST_HEAD(, foo) foohead; /* Head of global - foo list. */
- Avoid using typedefs for structure types. Typedefs are
- problematic
because they do not properly hide their underlying type; for - example you
need to know if the typedef is the structure itself or a - pointer to the
structure. In addition they must be declared exactly once, - whereas an
incomplete structure type can be mentioned as many times as - necessary.
Typedefs are difficult to use in stand-alone header files: - the header
that defines the typedef must be included before the header - that uses it,
or by the header that uses it (which causes namespace pollu - tion), or
there must be a back-door mechanism for obtaining the type - def.
- When convention requires a typedef, make its name match the
- struct tag.
Avoid typedefs ending in ``_t'', except as specified in - Standard C or by
POSIX. - /* Make the structure name match the typedef. */
typedef struct bar { - int level;
- } BAR;
typedef int foo; /* This is foo. */
typedef const long baz; /* This is baz. */ - All functions are prototyped somewhere.
- Function prototypes for private functions (i.e., functions
- not used elsewhere) go at the top of the first source module. Functions
- local to one
source module should be declared static. - Functions used from other parts of the kernel are prototyped
- in the relevant include file. Function prototypes should be listed in
- a logical
order, preferably alphabetical unless there is a compelling - reason to use
a different ordering. - Functions that are used locally in more than one module go
- into a separate header file, e.g. "extern.h".
- Do not use the __P macro.
- In general code can be considered ``new code'' when it makes
- up about 50%
or more of the file(s) involved. This is enough to break - precedents in
the existing code and use the current style guidelines. - The kernel has a name associated with parameter types, e.g.,
- in the kernel use:
- void function(int fd);
- In header files visible to userland applications, prototypes
- that are
visible must use either ``protected'' names (ones beginning - with an
underscore) or no names with the types. It is preferable to - use protected names. E.g., use:
- void function(int);
- or:
- void function(int _fd);
- Prototypes may have an extra space after a tab to enable
- function names
to line up: - static char *function(int _arg, const char *_arg2,
- struct foo *_arg3,
- struct bar *_arg4);
- static void usage(void);
- /*
- * All major routines should have a comment briefly describ
- ing what
* they do. The comment before the "main" routine should - describe
* what the program does.
*/ - int
main(int argc, char *argv[])
{ - char *ep;
long num;
int ch; - For consistency, getopt(3) should be used to parse options.
- Options
should be sorted in the getopt(3) call and the switch state - ment, unless
parts of the switch cascade. Elements in a switch statement - that cascade
should have a FALLTHROUGH comment. Numerical arguments - should be checked
for accuracy. Code that cannot be reached should have a - NOTREACHED comment.
while ((ch = getopt(argc, argv, "abNn:")) != -1)switch (ch) { /* Indent theswitch. */
case 'a': /* Don't indent thecase. */aflag = 1;
/* FALLTHROUGH */case 'b':bflag = 1;
break;case 'N':Nflag = 1;
break;case 'n':num = strtol(optarg, &ep, 10);
if (num <= 0 || *ep != ' ') {warnx("illegal number, -nargument -- %s",optarg);usage();}
break;case '?':
default:usage();
/* NOTREACHED */}- argc -= optind;
argv += optind; - Space after keywords (if, while, for, return, switch). No
- braces (`{'
and `}') are used for control statements with zero or only a - single
statement unless that statement is more than a single line - in which case
they are permitted. Forever loops are done with for's, not - while's.
for (p = buf; *p != ' '; ++p); /* nothing */- 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); - Parts of a for loop may be left empty. Do not put declara
- tions inside
blocks unless the routine is unusually complicated.
for (; cnt < 15; cnt++) {stmt1;
stmt2;- }
- Indentation is an 8 character tab. Second level indents are
- four spaces.
If you have to wrap a long statement, put the operator at - the end of the
line.
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;- Do not add whitespace at the end of a line, and only use
- tabs followed by
spaces to form the indentation. Do not use more spaces than - a tab will
produce and do not use spaces in front of tabs. - Closing and opening braces go on the same line as the else.
- Braces that
are not necessary may be left out.
if (test)stmt;- else if (bar) {
stmt;
stmt; - } else
stmt;
- No spaces after function names. Commas have a space after
- them. No
spaces after `(' or `[' or preceding `]' or `)' characters.
error = function(a1, a2);
if (error != 0)exit(error);- Unary operators do not require spaces, binary operators do.
- Do not use
parentheses unless they are required for precedence or un - less the statement is confusing without them. Remember that other people
- may confuse
easier than you. Do YOU understand the following?
a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
k = !(l & FLAGS);- Exits should be 0 on success, or according to the predefined
- values in
sysexits(3).
exit(EX_OK); /** Avoid obvious comments such as
* "Exit 0 on success."
*/- }
- The function type should be on a line by itself preceding
- the function.
The opening brace of the function body should be on a line - by itself.
- static char *
function(int a1, int a2, float fl, int a4)
{ - When declaring variables in functions declare them sorted by
- size, then
in alphabetical order; multiple ones per line are okay. If - a line overflows reuse the type keyword.
- Be careful to not obfuscate the code by initializing vari
- ables in the
declarations. Use this feature only thoughtfully. DO NOT - use function
calls in initializers.
struct foo one, *two;
double three;
int *four, five;
char *six, seven, eight, nine, ten, eleven, twelve;four = myfunction(); - Do not declare functions inside other functions; ANSI C says
- that such
declarations have file scope regardless of the nesting of - the declaration. Hiding file declarations in what appears to be a lo
- cal scope is
undesirable and will elicit complaints from a good compiler. - Casts and sizeof's are not followed by a space. Note that
- indent(1) does
not understand this rule. sizeof's are written with paren - thesis always.
The redundant parenthesis rules do not apply to sizeof(var) - instances.
- NULL is the preferred null pointer constant. Use NULL in
- stead of (type
*)0 or (type *)NULL in contexts where the compiler knows the - type, e.g.,
in assignments. Use (type *)NULL in other contexts, in par - ticular for
all function args. (Casting is essential for variadic args - and is necessary for other args if the function prototype might not be
- in scope.)
Test pointers against NULL, e.g., use: - (p = f()) == NULL
- not:
- !(p = f())
- Do not use ! for tests unless it is a boolean, e.g. use:
- if (*p == ' ')
- not:
- if (!*p)
- Routines returning void * should not have their return val
- ues cast to any
pointer type. - Values in return statements should be enclosed in parenthe
- ses.
- Use err(3) or warn(3), do not roll your own.
if ((four = malloc(sizeof(struct foo))) == NULL)err(1, (char *)NULL);- if ((six = (int *)overflow()) == NULL)
errx(1, "number overflowed");
- return (eight);
- }
- Old-style function declarations look like this:
- static char *
function(a1, a2, fl, a4) - int a1, a2; /* Declare ints, too, don't default
- them. */
float fl; /* Beware double vs. float prototype - differences. */
int a4; /* List in order declared. */ - {
- Use ANSI function declarations unless you explicitly need
- K&R compatibility. Long parameter lists are wrapped with a normal four
- space indent.
- Variable numbers of arguments should look like this:
- #include <stdarg.h>
- void
vaf(const char *fmt, ...)
{ - va_list ap;
- va_start(ap, fmt);
STUFF;
va_end(ap);
/* No return needed for void functions. */ - }
- static void
usage()
{ - /* Insert an empty line if the function has no local
- variables. */
- Use printf(3), not fputs(3), puts(3), putchar(3), whatever;
- it is faster
and usually cleaner, not to mention avoiding stupid bugs. - Usage statements should look like the manual pages SYNOPSIS.
- The usage
statement should be structured in the following order: - 1. Options without operands come first, in alphabetical
- order, inside a
single set of brackets (`[' and `]'). - 2. Options with operands come next, also in alphabetical
- order, with
each option and its argument inside its own pair of - brackets.
- 3. Required arguments (if any) are next, listed in the or
- der they
should be specified on the command line. - 4. Finally, any optional arguments should be listed, list
- ed in theorder they should be specified, and all inside brack
- ets.
- A bar (`|') separates ``either-or'' options/arguments, and
- multiple
options/arguments which are specified together are placed in - a single set
of brackets.
"usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1- [opt2]]0
"usage: f [-a | -b] [-c [-dEe] [-n number]]0
(void)fprintf(stderr, "usage: f [-ab]0);
exit(EX_USAGE);- }
- Note that the manual page options description should list
- the options in
pure alphabetical order. That is, without regard to whether - an option
takes arguments or not. The alphabetical ordering should - take into
account the case ordering shown above. - New core kernel code should be reasonably compliant with the
- style
guides. The guidelines for third-party maintained modules - and device
drivers are more relaxed but at a minimum should be inter - nally consistent
with their style. - Stylistic changes (including whitespace changes) are hard on
- the source
repository and are to be avoided without good reason. Code - that is
approximately FreeBSD KNF style compliant in the repository - must not
diverge from compliance. - Whenever possible, code should be run through a code checker
- (e.g.,
lint(1) or gcc -Wall) and produce minimal warnings.
SEE ALSO
HISTORY
- This manual page is largely based on the
- src/admin/style/style file from
the 4.4BSD-Lite2 release, with occasional updates to reflect - the current
practice and desire of the FreeBSD project. - BSD February 10, 2005