Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
STYLE(9)		   Kernel Developer's Manual		      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 examples.  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.110 2004/07/03 18:29:24 ru 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 sentences.  Fill
	* them so they look like real paragraphs.
	*/

       After  any  copyright  header, there is a blank line, and the rcsid for
       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	 else-
       where  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 renamed.

       #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.110 2004/07/03 18:29:24 ru Exp $");

       Leave another blank line	before the header files.

       Kernel  include	files  (i.e.  sys/*.h)	come  first; normally, include
       <sys/types.h> OR	<sys/param.h>, but not both.   <sys/types.h>  includes
       <sys/cdefs.h>, 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 <paths.h>.  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 namespace	except
       for implementing	application interfaces.

       The names of "unsafe" macros (ones that have  side  effects),  and  the
       names  of macros	for manifest constants,	are all	in uppercase.  The ex-
       pansions	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	function,  the
       function	 name  is all in lowercase and the macro has the same name all
       in uppercase.  Right-justify the	backslashes; it	 makes	it  easier  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
       confusing to the	reader.	 Exceptions may	be made	for cases  where  code
       is  conditionally not compiled for the purposes of lint(1), even	though
       the uncompiled region may be small.  The	comment	 should	 be  separated
       from  the  #endif  or #else by a	single space.  For short conditionally
       compiled	regions, a closing comment should not be used.

       The comment for #endif should match the expression used in  the	corre-
       sponding	 #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 "defined(FOO)"  is  ab-
       breviated  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 preference	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 overrid-
       ing  reason  to	prefer the older BSD-style.  Like white-space commits,
       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	 adja-
       cent  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 iden-
       tifiers from asterisks using a single space.

       When  declaring	variables  in  structures, declare them	sorted by use,
       then by size, and then in alphabetical order.  The first	category  nor-
       mally  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 declarations
       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 mumble. */
	       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	possi-
       ble.  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 mumble. */
	       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 be-
       cause  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  pollution),
       or there	must be	a back-door mechanism for obtaining the	typedef.

       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 logi-
       cal  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 sepa-
       rate 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  un-
       derscore)  or  no  names	 with the types.  It is	preferable to use pro-
       tected 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 describing 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 statement,	unless
       parts  of the switch cascade.  Elements in a switch statement that cas-
       cade 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 the switch. */
		       case 'a':	       /* Don't	indent the case. */
			       aflag = 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();
			       /* 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	!= '\0'; ++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 declarations	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 unless 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 variables	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 declara-
       tion.  Hiding file declarations in what appears to be a local 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  parenthesis
       always.	 The  redundant	 parenthesis rules do not apply	to sizeof(var)
       instances.

       NULL is the preferred null pointer constant.  Use NULL instead 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 particu-
       lar 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 == '\0')

       not

       if (!*p)

       Routines	 returning  void * should not have their return	values cast to
       any pointer type.

       Values in return	statements should be enclosed in parentheses.

       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  compati-
       bility.	 Long parameter	lists are wrapped with a normal	four space in-
       dent.

       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 us-
       age 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  order  they
	    should be specified	on the command line.

       4.   Finally,  any  optional  arguments should be listed, listed	in the
	    order they should be specified, and	all inside brackets.

       A bar (`|') separates "either-or" options/arguments, and	 multiple  op-
       tions/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]]\n"
	   "usage: f [-a | -b] [-c [-dEe] [-n number]]\n"

	       (void)fprintf(stderr, "usage: f [-ab]\n");
	       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  op-
       tion  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 internally  consis-
       tent 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 ap-
       proximately  FreeBSD KNF	style compliant	in the repository must not di-
       verge 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
       indent(1), lint(1), err(3), sysexits(3),	warn(3), style.Makefile(5)

HISTORY
       This  man  page is largely based	on the src/admin/style/style file from
       the 4.4BSD-Lite2	release, with occasional updates to reflect  the  cur-
       rent practice and desire	of the FreeBSD project.

GNU			       December	7, 2001			      STYLE(9)

NAME | DESCRIPTION | SEE ALSO | HISTORY

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=style&sektion=9&manpath=FreeBSD+5.3-RELEASE>

home | help