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.105 2003/11/12 10:53:52 fanf	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.105 2003/11/12 10:53:52 fanf 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's 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, "abn:"))	!= -1)
		       switch (ch) {	       /* Indent the switch. */
		       case 'a':	       /* Don't	indent the 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;

       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.

FreeBSD	5.2.1		       December	7, 2001			      STYLE(9)

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

home | help