Programming Discipline and Software Development Environment

A good programming discipline and software development environment go a long way in doing productive and efficient work. Here is a list:

  1. Lots of programming errors can be avoided by proper usage of tools for compilation & static code analysis.
  2. For compilation, one should always use -Wall option. For example:
    gcc -Wall myprogram.c
    For static code analysis, “splint” utility.
  3. The software development environment must have a Makefile, even if one has a single C file. The advantage will become obvious as the number of C files and header files grows over a period of time.
  4. In a big project, one needs to search for files, function names, variable names, and so on.  One can use “cscope” and/or “ctags” utilities for this purpose.
  5. All programs must follow a good C coding guideline. For Linux and C programming, one should look at guidelines used by Linux kernel developers.

Mentioned below is a derived version of this C coding style used at Sanfoundry.

1. Indentation

advertisement
advertisement

The code must be indented properly. Use tabspaces for indentation. Web developers should use 2 space characters instead of tab space for web publishing (For example publishing a post on sanfoundry.com).

Indentation level 0 -> align to column 1
Indentation level 1 -> indent by 1 tab to the right of indentation level 0
Indentation level n+1 -> indent by 1 tab to the right of indentation level n

Indentation levels in a switch statement are to align the “switch” and “case” labels in the same column. For example:

	switch (var) {
	case 't':
                avar = 10;
                break;
	case 'u':
                avar = 20;
                break;
	default:
                break;
	}

2. Breaking Long Lines and Strings

Don’t put multiple statements on a single line.
Don’t put multiple assignments on a single line either.
Don’t leave whitespace at the end of the lines.

The maximum length of a line should be 80 columns. Statements longer than 80 columns will be broken into sensible chunks. For example:

void fun(int a, int b, int c)
{
	if (condition)
                printf("Warning this is a long printf with 3 parameters"
                       " a: %u b: %u c: %u n", a, b, c);
	else
                next_statement;
}

3. Placing Braces and Spaces

advertisement

Put the opening brace last on the line, and put the closing brace first, thus:

	if (x is true) {
             we do y
	}

This applies to all non-function statement blocks (if, switch, for, while, do). E.g.:

	switch (var) {
	case 't':
                avar = 10;
                break;
	case 'u':
                avar = 20;
                break;
	default:
                break;
	}

However, there is one special case, namely functions: they have the opening brace at the beginning of the next line, thus:

advertisement
	int function(int x)
	{
                body of function
	}

Note that the closing brace is empty on a line of its own, _except_ in the cases where it is followed by a continuation of the same statement, ie a “while” in a do-statement or an “else” in an if-statement, like this:

	do {
                body of do-loop
	} while (condition);

and

	if (x == y) {
                ...
	} else if (x > y) {
                ...
	} else {
                ...
	}

Do not unnecessarily use braces where a single statement will do.

if (condition)
        action();

and

if (condition)
        do_this();
else
        do_that();

This does not apply if one branch of a conditional statement is a single statement. Use braces in both branches.

if (condition) {
        do_this();
        do_that();
} else {
        otherwise();
}

3.1. Spaces

Use a space after (most) keywords. The notable exception is sizeof. So use a space after these keywords: if, switch, case, for, do, while but not with sizeof keyword. For example:

if(a > b) is bad.
if (a > b) is good.
 
for(i = 0; i < n; i++) is bad. 
for (i = 0; i < n; i++) is good.
 
sizeof (struct file) is bad.
sizeof(struct file) is good.

Do not add spaces around (inside) parenthesized expressions. This example is *bad*:

    s = sizeof( struct file );

This is good:

    s = sizeof(struct file);

When declaring pointer data or a function that returns a pointer type, the preferred use of ‘*’ is adjacent to the data name or function name and not adjacent to the type name. Good examples:

char *p;
unsigned strlen(char *ptr);
 
Use one space around (on each side of) most binary and ternary operators, such as any of these:
	=  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :
 
but no space after unary operators:
	&  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined
 
no space before the postfix increment & decrement unary operators:
	++  --
 
no space after the prefix increment & decrement unary operators:
	++  --
 
and no space around the '.' and "->" structure member operators.
 
Do not leave trailing whitespace at the ends of lines.

3.2 Spaces in function arguments

If a function has multiple arguments, then put a space after comma. For example:

sum(a,b) is bad.
sum(a, b) is good.
 
printf("a = %d, b = %dn",a,b) is bad.
printf("a = %d, b = %dn", a, b) is good.

4. Naming
Don’t use cute names like ThisVariableIsATemporaryCounter.
Don’t use mixed-case names. Always use lower case names.
For global variables and functions, use meaningful & descriptive names.
For example:

    int foo(int); /* foo() is a bad name for global function name */
    void encode(char *); /* ecnode() is a good global function name */
    void count_active_users(void): /* good descriptive name */

LOCAL variable names should be short, and to the point. If you have some random integer loop counter, it should probably be called “i”. Calling it “loop_counter” is non-productive. Similarly, “tmp” can be just about any type of variable that is used to hold a temporary value. For example:

    int i;
    int tmp;
    char c;
    char *p;

5. Commenting

Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment. Generally, you want your comments to tell WHAT your code does, not HOW.

Also, try to avoid putting comments inside a function body.

The preferred style for long (multi-line) comments is:

        /*
         * This is the preferred style for multi-line comments in the
         * source code. Please use it consistently.
         *
         * Description:  A column of asterisks on the left side,
         * with beginning and ending almost-blank lines.
         */

6. Macros & Enums

Names of macros defining constants and labels in enums are capitalized. For example:

#define CONSTANT 0x12345

Enums are preferred when defining several related constants.

That’s all Folks.

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.