C language is widely used in embedded programming and many programmers write programs in their own style. Sometimes it is very diffcult for programmers to understand
and maintain code written by other programmers. So it is better to have some set of rules and adhere to that while writing programs.
The rules and recommendations presented here are not the only set of rules to be followed, but it can be used as a basis for writing C programs.
I have explained the rules in different categories of C language. The rules are classified under two categories : Required and Advisory.
Required means that rule has to be strictly followed and advisory means it can be followed but not mandatory.
1. File Structure
Rule 1 ( Required )
Include files in C always have the file name extension ".h"
Rule 2 ( Required )
Implementation files in C always have the file name extension ".c".
Rule 3 ( Required )
Divide up the definitions of functions into as many files as possible.
Rule 4 ( Advisory )
Place machine-dependent code in a special file so that it may be easily located when porting code from one machine to another.
Rule 5 ( Required )
Always give a file a name that is unique in as large a context as possible.
Rule 6 ( Required )
File names must be in mixed case starting with lower case
Rule 7 ( Required )
Every include file must contain a mechanism that prevents multiple inclusions of the file.
Rule 8 ( Required )
Use the directive #include "filename.h" for user-prepared include files.
Rule 9 ( Required )
Use the directive #include for include files from libraries.
Rule 10 ( Advisory )
If a file only contains information that is only needed in an implementation file, that file should not be included in another include file.
Rule 11 ( Required )
All function definitions should reside in implementation files
Rule 12 ( Advisory )
Include statements should be sorted and grouped. Sorted by their hierarchical position in the system with low level files included first. Leave an empty line
between groups of include statements.
Rule 13 ( Required )
Always give the project workspace file a name that is unique in as large a context as possible.
Rule 14 ( Required )
Don’t use absolute pathnames for header files. Use the construction for getting them from a standard place, or define them relative to the current directory.
Rule 15 ( Required )
Global ( Extern ) variables and structures are declared ( .h ) and defined ( .c ) in separate files
2. Naming Conventions
Rule 16 ( Required )
The names of variables, constants, and functions are to begin with a lowercase letter.
Rule 17 ( Required )
The declarations for Structures should be in the format given below
Rule 18 ( Required )
The declarations for Enumerations should be in the format given below
Rule 19 ( Required )
In names which consist of more than one word, the words are written together and each word that follows the first is begun with an uppercase letter.
Rule 20 ( Advisory )
Do not use typenames that differ only by the use of uppercase and lowercase letters.
Rule 21 ( Advisory )
Names should not include abbreviations that are not generally accepted.
Rule 22 ( Required )
Choose variable names that suggest the usage.
Rule 23 ( Required )
Named constants (including enumeration values) must be all uppercase using underscore to separate words.
Rule 24 ( Required )
Iterator variables should be called index1, index2, index3 etc..
Rule 25 ( Advisory )
The prefix is should be used for boolean variables and methods.
Rule 26 ( Advisory )
Enumeration constants can be prefixed by a common type name.
3. Control Flow
Rule 27 ( Advisory )
If a conditional expression always has the same result, there is no need for the condition.
Rule 28 ( Advisory )
The control variable in a for loop should be tested against a constant value, not a function or expression.
Rule 29 ( Advisory )
When testing incrementing or decrementing counters try to use the >= or <= instead of == in if-statements. If for some reason the value of the counter gets
higher or lower than expected in the test for equal you would run into problems.
4. Functions
Rule 30 ( Required )
Always write the left parenthesis directly after a function name
Rule 31 ( Required )
Function names must identify the action performed or the information provided by the function.
Rule 32 ( Required )
Do not have overly complex functions.
The number of control flow primitives( if, else, for etc ) in a function should be minimal
Rule 33 ( Advisory )
Do not use ellipsis '...' in function parameters.
Use of the ellipsis notation (...) to indicate an unspecified number of arguments should be avoided. It is better to develop specific methods for all
situations. Use of ellipsis defeats the type checking capability of C++
5. Variables and Constants
Rule 34 ( Required )
The use of magic numbers in the code should be avoided. Numbers other than 0 and 1 should be considered declared as named constants instead
Rule 35 ( Required )
Use of global and static variables should be avoided
Rule 36 ( Required )
Pointers and references should have their reference symbol next to the type rather than to the name.
Rule 37 ( Required )
Declare each variable on a separate line in a separate declaration statement. If the declaration is not self-explanatory, append a comment describing the variable.
Rule 38 ( Required )
Variables should be initialized in separate statements
Rule 39 ( Required )
Static variables should be explicitly initialized to 0
6. Pointers
Rule 40 ( Required )
Do not compare a pointer to NULL or assign NULL to a pointer; use 0 instead.
Rule 41 ( Required )
Pointers to pointers should whenever possible be avoided.
7. Comments
Rule 42 ( Required )
All files must include copyright information.
Rule 43 ( Required )
Every file that contains source code must be documented with an introductory comment that provides information on the file name and its contents.
Rule 44 ( Required )
All comments are to be written in English.
Rule 45 ( Required )
Write some descriptive comments before every function.
Rule 46 ( Required )
Use /* */ for all comments, including multi-line comments.
Rule 47 ( Required )
Tricky code should not be commented but rewritten
Clear code is preferable to well-commented messy code. Every effort should be made to make code clear through good design, simplicity, good naming and layout.
Comments are definitely required where code is not clear.
Rule 48 ( Advisory )
All comments in source code files must be up-to-date at all times during that code's lifetime.
8. Spacing , Indentation , Code Style
Rule 49 ( Required )
There should be only one operation per line.
Rule 50 ( Required )
Use spaces instead of tabs in a source file.The tab size for source files should be set to every three spaces.
Rule 51 ( Required )
Conventional operators should be surrounded by a space character.
Rule 52 ( Required )
Matching braces (‘{‘ ’}’) should line up vertically inline with the parent statement
Rule 53 ( Required )
Place single spaces immediately after commas, round brace in routine parameter lists, Control Flow Structures ( if,while,for ,switch etc )
Rule 54 ( Advisory )
Place single line space between blocks of code for better readability
Rule 55 ( Required )
Place single line space between variable declaration and statements inside the function
Rule 56 (Required)
Write only one function parameter per line in function declaration, definition
Rule 57 (Required)
Parenthesis should be used for return value
Rule 58 ( Required )
Do not use spaces around `.' or `->', nor between unary operators and operands.
Rule 59 ( Required )
Write switch and case keywords on the same level
Rule 60 ( Required )
One line spacing between if and else is not needed.
Rule 61 ( Required )
While using if-else if -else ,Else should be separated from if
9. Compiler Settings
Rule 62 ( Required )
While building the final exe file the mode of the compiler should be in ‘ Release ‘ and not ‘ Debug ‘
Rule 63 ( Required )
If the compiler supports any code checking standards like MISRA C enable that option
Rule 64 ( Advisory )
While compiling it is a good practice to set compiler warning levels to the maximum level. Eliminate warnings by changing your code, not by reducing the
warning level.
10. Portable code
Rule 65 ( Advisory )
Use explicit type conversions for arithmetic using signed and unsigned values.
Rule 66 ( Advisory )
Do not use compiler specific language or pre-processor extensions.
Rule 67 ( Advisory )
Organize source files so that the machine-independent code and the machine-dependent code are inseparate files. Then if the program is to be moved to a new machine,
it is a much easier task to determinewhat needs to be changed.
Rule 68 ( Required )
Always treat include file names as case-sensitive.
Rule 69 ( Advisory )
Do not depend on the order of evaluation of arguments to a function.The order of evaluation of function arguments is strongly compiler dependent.
Never use ++, -- operators on method arguments in function calls.
11. Optimization Techniques
Usage of For Loop
Try using decrementing for loop instead of incrementing for loop.
Passing Parameters to a function
It is better to have structure/ union pointers passed as function parameters instead of structure/ union instances. This is because if a structure/ union as a whole is passed
all the members will be passed as parameters which will increase the code memory. Instead pointers can be passed as parameters.
12. General Recommendations
- File content must be kept within 80 columns.
Naming Conventions
- The terms get/set must be used where an attribute is accessed directly.Eg. employee.getId(); employee.setId(id);
- The term compute can be used in methods where something is computed.Eg. valueSet->computeSum();
- The term find can be used in methods where something is looked up.Eg: vertex.findNearestVertex();
- Complement names must be used for complement operations
Eg : get/set, add/remove, create/destroy, start/stop, insert/delete, increment/decrement, old/new, begin/end, first/last, up/down, min/max, next/previous, old/new,
open/close, show/hide, suspend/resume, etc.
- It is also a good practice to keep track of the software versions and the Bugs found.
- It is always a good practice to have keep regular backups of the software.