Translation


by Transposh

Archive for the ‘C Programming’ Category

Coding Best Practices for C – Part – 2

Tuesday, October 13th, 2009

My last blog was about standards for naming conventions in C. Here we will discuss some very serious stuff,which we can’t ignore while writing code, by any means.This will help you to create a robust and easily maintainable code.

This is very useful, while creating a variable, using an operator, or writing an expression.

STANDARDS

  • Do not use extern variables.
  • Explicitly declare the type of all variables.
  • Variables should be explicitly initialized.
  • Global variables should be avoided unless they are really necessary, and good reasons should be given for their use.
  • Let the compiler work out the length of objects: use sizeof rather than declaring structure lengths explicitly.
  • Use a cast explicitly when converting unusual types; otherwise in general allow the compiler to do the casting.
  • Avoid machine dependent fill methods. Do not apply right shift (>>) or left shift (< <) operators to signed operands, and do not use shifts to perform division or multiplication. Clearly noted exceptions are allowed.
  • Do not write code that depends on the byte order of a particular architecture, nor on particular word alignment boundaries.
  • Uninitialized automatic variables must never be used. This is detected by lint.
  • Pointer assignment shall be between pointers of the same type (void * is an exception, though it should be used only with good reason).
  • void treating pointers as integers or vice versa.The “pointer” qualifier, ‘*’, should be with the variable name rather than with the type. Example:
    char  *s, *t, *u; instead of char*  s,t,u;
  • Check the validity of a pointer, before using. Compare it to a typecast NULL. Do not use the integer 0.  Note that stdio.h must be included to define NULL.
  • Give structures, unions, and enumerations defined-type names using typedef for definitions which are used outside of a single function
    A typedef, instead of a macro definition (#define), should be used to provide an alternate name for a type.
  • The const qualifier should be used for variables that do NOT change.
  • Numerical constants should not be coded directly.   i.e., Do NOT hard-code numeric or string constants in program text.
  • Static local variables should only be used when it is necessary to maintain a value from one invocation of a function to the next.
  • The pointer variable void * should only be used as a temporary holding place.  No pointer arithmetic should be performed with it.
  • Unary operators should not be separated from their single operand.  Generally, all binary operators except ‘.’ and ‘->’ should be separated from their operands by blanks.  Some judgment is called for in the case of complex expressions, which may be clearer if the “inner” operators are not surrounded by spaces and the “outer” ones are.
  • System defined symbols such as NULL, EOF, \f, etc. should be used where appropriate to promote portability.

GUIDELINES

  • Beware of side effects in macro parameters. Don’t use increment or decrement operators on macro arguments; if the macro references the argument more than once the increment or decrement will be repeated.
  • To improve clarity use parentheses even when not required. Using parentheses also helps avoid errors caused by misunderstood operator precedence.
  • Provide an in line comment for each variable declaration (except for obvious loop counters).
  • Avoid local declarations that override declarations at higher levels.
  • Unrelated declarations, even of the same type, should be on separate lines.
  • Do NOT use the assert facility.  Any exceptions should be referred to a TA for review and resolution.
  • Bit manipulations should be formed only on unsigned integers.
  • If you use enums, the first enum constant should be initialized, or the first constant should indicate an error.   For example:
    enum {STATE_ERR, STATE_START, STATE_NORMAL, STATE_END} state_t;
    enum {VAL_NEW=1, VAL_NORMAL, VAL_DYING, VAL_DEAD} value_t;






Variablesezx, Operators

Coding Best Practices for C – Part – 1

Sunday, October 11th, 2009

“Hello world” is the first lesson in any language. We always always try to improve our coding knowledge.  But for a professional development we should follow good and generic standards for writing a code. With my experience in C,I understood the fact,that writing a code is not a great thing. But writing a error free code in small span of time and  which can be referred or enhanced by other developers without any confusion makes a perfect code. As I strongly believe, Today’s best solutions becomes tomorrows Best Practices. We need to learn form our mistake and others experience to become perfect.

With this perception I would like to share my experience to enrich your Coding experience.

Here is some standard for coding C that you can follow to get the best result, and can save your life from Reviewer’s comments.

If you have below goals in mind:

  • Code should be robust and error free.
  • Code should be easy to use and understand.
  • Code should be easy to maintain.

This is for you.

Naming Conventions

General:

  • Clear and informative names are one of the best tools for creating easily understandable code. The name of any identifier should   succinctly describe the purpose of that identifier.
  • Avoid abstract names (in a global context) that are likely to be reused by other parts of the system.

File Names:

  • Header(.h) files should have the same name as the .c for header files dedicated to the .c.
  • File names should be made up of a prefix, underscore, base name, period and suffix.  File names should be consistent with the area of the application being modified.  File names should represent the content or role of the file.
  • Header file names should have the extension “.h”.
  • C Implementation (source) file names should have the extension “.c”

Function Names:

  • Function names should reflect what they do or what they return.
  • Do NOT re-use names of functions from the standards libraries (such as printf or strlen).
  • Function names should normally be formed from two parts: an action (verb) and an object (noun) of the action. Exceptions are query functions where the second part is not a noun, but the name should form a “question”.
    eg. GetSystemTime() SetStringLength()

Variable Names:

  • Variable names should be descriptive of the variable’s functions.
  • Constant names should be in all CAPS, with multiple words separated by an underscore, e.g.  MAX_PAGERS.
  • Macros, with or without parameters, should also be in all CAPS.
  • Enumeration constants and global typedef names should be in all CAPS with individual words separated by underscores, e.g. DATA_VALID.