Basic Style

There are some basic style elements that I use; in this section I'll go over the elements, and why they are being used.

Rules

Style is personal. Everyone has there favorite style. In general, there are no good or bad styles; just ones you like. The styles in this section are what I like and use; if you agree with their rationale, then use them.

About the only hard rules I would recommend about style are:

Names

Every ADT element, starting with the file name, should share the same root. In the case of the ADT int_stack:

Using a systematic approach to naming entities has several benefits:

Function Definition


	void
	destroy_int_stack(

When defining a function, I place the name of the function at the start of the line. Note that this requires the type of the function to be on on the previous line.

Placing the name of the function at the start of the line allows me to answer "where is the function defined?" by looking for start of line followed by function name. For example, if I were editing int_stack.c using vi, I would look for the definition of make_int_stack using:


	/^make_int_stack

Alternatively, assume that there was some large ADT which was implemented using several .c files. In that case we could use the same technique to isolate the file.


	grep '^function_name' type_name*.c

This should be used to supplement, not replace, tags.

Parameters


	void
	push_int_stack(
		int_stack	stack,
		int		val	/* value being pushed */
		)

Each parameter in a function definition is placed on a line by itself.

The indenting method used (a tab before the type name, all argument names lined up in the same column using tabs) was picked to enhance readability by other, later, users/maintainers.

If the function has no parameters the void is written on the same line as the function name.

Function Body


	int_stack
	make_int_stack(void)
	{
  	/* ... */
	}

The braces for the body of the function appear on lines by themselves, at the start of the line. This allows us to conveniently move to the beginning/end of the function while editing.

Variable declarations


	void
	push_int_stack(
		int_stack	stack,
		int		val
		)
	{
  	int		len = len_int_stack(stack);
  	int		max = max_int_stack(stack);
  	int		nmax;
  	int *		vals;
  	int *		nvals;
  	int		i;
	
  	/* ... */
	}

Declarations use the following style:

There are various reasons for picking this style. They make it easier to read and understand the code, and more convenient to modify it.

Indenting

I indent by two spaces. Why?

Thus, to me, an indent of 2 spaces is an adequate compromise between visually offsetting different nesting levels and preventing line overflows.

Brace placement


	if( ... ) {
	  /* ... */
	}
	else {
	  /* ... */
	}

	for( ... ) {
	  /* ... */
	}

The braces delimiting the block following a control statement have the following style:

I would like to keep the number of lines down, so that I can have as much code as possible on a screen. This aids comprehension. Consequently, the opening braces are on the same line as the control statement. However, this rule should not decrease the readability of the code. Consequently, the closing braces are on a line by themselves, so that it is visually clear where the basic block ends.

Single line blocks


	if( stack == 0 ) {
	  PANIC("out of memory");
	}

	for( i = 0; i < len; i++ ) {
	  nvals[i] = vals[i];
	}

Always enclose the block after a control structure such as an if or for with braces. Do this even if the block has a single statement, and does not require the braces.

Often times, when people debug, they add debug printf() and assert() statements to the code. Sometimes they need to add code to these single-statement blocks. At that point, the block will become a two statement block, so it should be enclosed in braces. Unfortunately, there is a chance that this will not happen, and the code will end up looking like:


	for(i = 0; i < len; i++ ) 	/* NOTE: no braces */
	  printf("i=%d val=%d\n", i, vals[i]); /* the debug statement */
	  nvals[i] = vals[i];		/* OOPS! not part of the for anymore */

These kinds of bugs will happen. Avoid them by always adding the extra braces.

Empty blocks


	/* compute the ceil(log2(x)); i,x are unsigned; x is not 0 */
	for( i = x>>1, n = 0; i != 0; i >>= 1, n++ ) {
	}

In C we can have loops that have nothing in their body. We should use braces around an empty body. This allows us to expand the body if necessary. Further it gives us a visual clue that something out-of-the-normal is going on.


Next Prev Main Top Feedback