Difference between revisions of "PKI C Coding Style"

From Dogtag
Jump to: navigation, search
(Functions)
(Variable Declarations)
 
(17 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This manual contains the C coding standards and guidelines for Fedora Certificate System contributors.
 
 
This project has evolved over a very long time (see [[Roadmap#History|History]]). As a result not all of the existing code conforms to these standards. All new C code should adhere to these standards but please do not go back and make wholesale formatting changes to the old code. It just confuses things and is generally a waste of time.
 
 
 
== Why Have A Coding Style? ==
 
== Why Have A Coding Style? ==
  
Line 19: Line 15:
 
** Space after keywords
 
** Space after keywords
 
** Curly braces on new line following a function/subroutine.
 
** Curly braces on new line following a function/subroutine.
** Curly braces on same line as if/while.
+
** Curly braces on same line as if/while/switch.
 
* Prefer NSPR functions for file, string, memory allocation, etc. if at all possible.
 
* Prefer NSPR functions for file, string, memory allocation, etc. if at all possible.
 
* All code should be peer reviewed before being checked in.
 
* All code should be peer reviewed before being checked in.
  
== Functions ==
+
== Functions and Subroutines ==
 +
* functions should have the following form:
  
 
  int foo(int bar)
 
  int foo(int bar)
 
  {
 
  {
 +
    if (something) {
 +
        /* stuff done here */
 +
        return 1;           
 +
    }
 +
   
 +
    return 0;
 +
}
 +
 +
'''NOT''' like this:
 +
 +
int foo(int bar) {
 
     if (something) {
 
     if (something) {
 
         /* stuff done here */
 
         /* stuff done here */
Line 37: Line 45:
 
== Statements ==
 
== Statements ==
  
* if-else statements should have the following form.
+
* if-else statements should have the following form:
  
 
     if (''condition'') {
 
     if (''condition'') {
Line 60: Line 68:
 
     }
 
     }
  
* Always use braces, even if there's only one line for both (this allows for easier debugging in the future):
+
* Always use braces, even if there's only one line for both portions of an if-else statement:
  
 
     if (foo) {
 
     if (foo) {
Line 70: Line 78:
 
* Avoid last-return-in-else problem.  Code should look like this:
 
* Avoid last-return-in-else problem.  Code should look like this:
  
     int foo(int bar) {
+
     int foo(int bar)
 +
    {
 
         if (something) {
 
         if (something) {
 
             /* stuff done here */
 
             /* stuff done here */
Line 81: Line 90:
 
'''NOT''' like this:
 
'''NOT''' like this:
  
     int foo(int bar) {
+
     int foo(int bar)
 +
    {
 
         if (something) {
 
         if (something) {
 
             /* stuff done here */
 
             /* stuff done here */
Line 116: Line 126:
 
== Comments ==
 
== Comments ==
  
* C-style comments are preferred (/* */ instead of //)
+
* Always use C-style comments in C programs, not C++-style comments (/* */ instead of //)
 
** Each function should be preceeded with a block comment describing what the function is supposed to do.
 
** Each function should be preceeded with a block comment describing what the function is supposed to do.
 
** Block comments should be preceeded by a blank line to set it apart. Line up the * characters in the block comment.
 
** Block comments should be preceeded by a blank line to set it apart. Line up the * characters in the block comment.
Line 131: Line 141:
 
** after a comma
 
** after a comma
 
** before an operator
 
** before an operator
** align the new line with the beginnigng of the expression at the same level in the previous line
+
** align the new line with the beginning of the expression at the same level in the previous line
 
** if all else fails, just indent 8 spaces.
 
** if all else fails, just indent 8 spaces.
  
  Function(longArgument1, longArgument2, longArgument3,  
+
  function(longArgument1, longArgument2, longArgument3,  
 
           longArgument4, longArgument5);
 
           longArgument4, longArgument5);
  
Line 149: Line 159:
 
* Initialize at declaration time when possible.
 
* Initialize at declaration time when possible.
 
* Declare variables at the beginning of a block to maintain C99 compatibility.
 
* Declare variables at the beginning of a block to maintain C99 compatibility.
 
* No tabs, use spaces.  Your editor should take care of most of this but in patches tabs stick out like sore thumbs.
 

Latest revision as of 05:22, 21 March 2008

Why Have A Coding Style?

For easier maintenance

If you're merging changes from a patch it's much easier if everyone is using the same coding style. This isn't the reality for a lot of our code, but we're trying to get to the point where most of it uses the same style.

Improved readability

Remember, code isn't just for compilers, it's for people, too. If it wasn't for people, we would all be programming in assembly. Coding style and consistency mean that if you go from one part of the code to another you don't spend time having to re-adjust from one style to another. Blocks are consistent and readable and the flow of the code is apparent. Coding style adds value for people who have to read your code after you've been hit by a bus. Remember that.

General Rules

  • All source and header files should include a copy of the license.
  • Stick to a K&R coding style.
    • Space after keywords
    • Curly braces on new line following a function/subroutine.
    • Curly braces on same line as if/while/switch.
  • Prefer NSPR functions for file, string, memory allocation, etc. if at all possible.
  • All code should be peer reviewed before being checked in.

Functions and Subroutines

  • functions should have the following form:
int foo(int bar)
{
    if (something) {
        /* stuff done here */
        return 1;            
    }
   
    return 0;
}

NOT like this:

int foo(int bar) {
    if (something) {
        /* stuff done here */
        return 1;            
    }
   
    return 0;
}

Statements

  • if-else statements should have the following form:
   if (condition) {
       /* do some work */
   }
   if (condition) {
       /* do some work */
   } else {
       /* do some other work */
   }
  • Balance the braces in the if and else in an if-else statement if either has only one line:
   if (condition) {
       /*
        * stuff that takes up more than one
        * line
        */
   } else {
       /* stuff that only uses one line */
   }
  • Always use braces, even if there's only one line for both portions of an if-else statement:
   if (foo) {
       bar();
   } else {
       baz();
   }
  • Avoid last-return-in-else problem. Code should look like this:
   int foo(int bar)
   {
       if (something) {
           /* stuff done here */
           return 1;            
       }
   
       return 0;
   }

NOT like this:

   int foo(int bar)
   {
       if (something) {
           /* stuff done here */
           return 1;            
       } else {
           return 0;
       }
   }
  • for, while and until statements should take a similar form:
   for (initialization; condition; update) {
       /* iterate here */
   }
   while (condition) {
       /* do some work */
   }
  • switch statements:
   switch (condition) {
   case A:
       /* do work */
       break;
   case B:
       /* do work */
       break;
   default:
       /* do work */
       break;
   }

Comments

  • Always use C-style comments in C programs, not C++-style comments (/* */ instead of //)
    • Each function should be preceeded with a block comment describing what the function is supposed to do.
    • Block comments should be preceeded by a blank line to set it apart. Line up the * characters in the block comment.
/*
 * A block comment.
 */

Indentation

  • Try to keep lines 80 characters or less.
  • Indentation is 4 spaces.
  • No tabs, use spaces. Your editor should take care of most of this but in patches tabs stick out like sore thumbs.
  • When wrapping lines, try to break it:
    • after a comma
    • before an operator
    • align the new line with the beginning of the expression at the same level in the previous line
    • if all else fails, just indent 8 spaces.
function(longArgument1, longArgument2, longArgument3, 
         longArgument4, longArgument5);

Variable Declarations

  • One declaration per line is preferred.
   int foo;
   int bar;

instead of

  int foo, bar;
  • Initialize at declaration time when possible.
  • Declare variables at the beginning of a block to maintain C99 compatibility.