Code Documentation Excerpts
Code Documentation Excerpts
Code Documentation Excerpts
Preliminary Version
Table Of Contents
1. INTRODUCTION
1.1 PURPOSE 5
1.2 Scope 6
1.6 References 7
4.1 Use constants and macros instead of hard coded literal values 14
6. SUBROUTINES 15
7. COMMENTS 16
8. CODE LAYOUT 17
9.6 Use of upper/lower case and underscores to differentiate Subroutines, Variables, and Constants. 22
9.8 Variables 22
AUTHOR(s): APPROVED: Revised:
9.10 Use of prefix (Hungarian) notations to differentiate the scope and type of a data variable 22
9.10.1 Identifying data types 23
9.11 Abbreviations 25
10.7 Type casting integer and float variables makes code more portable 28
10.9 Use ASCII files for runtime or machine dependent constants and macros 29
10.11 Debugging 29
11.3 Cohesion 30
11.4 Coupling 30
1. INTRODUCTION
1.1 PURPOSE
The goal of these guidelines is to create uniform coding habits among software personnel in the
engineering department so that reading, checking, and maintaining code written by different persons
becomes easier. The intent of these standards is to define a natural style and consistency, yet leave
to the authors of the engineering department source code, the freedom to practice their craft without
unnecessary burden.
Experience over many projects points to the conclusion that coding standards help the project to
run smoothly. They aren’t necessary for success, but they help. Most arguments against a
particular standard come from the ego. Few decisions in a reasonable standard really can be said to
be technically deficient, just matters of taste. So, in the interests of establishing the engineering
department as a showcase software development environment, be flexible, control the ego a bit, and
remember any project is a team effort.
A mixed coding style is harder to maintain than a bad coding style. So it’s important to apply a
consistent coding style across a project. When maintaining code, it’s better to conform to the style
of the existing code rather than blindly follow this document or your own coding style.
Since a very large portion of project scope is after-delivery maintenance or enhancement, coding
standards reduce the cost of a project by easing the learning or re-learning task when code needs to
be addressed by people other than the author, or by the author after a long absence. Coding
standards help ensure that the author need not be present for the maintenance and enhancement
phase.
1.2 Scope
This document describes general software coding standards for code written in any text based
programming language (including high-level languages like C, C++, Basic, Visual Basic, and assembler
languages). Many of the guidelines described in this document can be directly applied to
programming practices in graphical based languages ( such as PLC, graphical, and visual languages).
This will be used as the base document for several language specific coding standard documents.
Each language specific coding standard will be written to expand on these concepts with specific
examples, and define additional guidelines unique to that language.
For each project, this document will be used in conjunction with language and project specific coding
standards that, in total define a complete set of coding standards. A description of the general,
language specific, and project specific coding standards is provided below:
• An “identifier” is the generic term referring to a name for any constant, variable, or program
unit.
• A “module” is a collection of “units” that work on a common domain.
1.6 References
a. General Coding Standards, Author (s) unknown
b. Steve McConnell, Code Complete, Microsoft Press 1996 (ISBN 1-55615-484-4)
c. Writing Solid Code, Steve McConnell, Microsoft Press 1996 (ISBN 1-55615-551-4)
d. A Modest Software Standard, Jack G. Ganssle, March 1996 Embedded Systems Programming
e. Recommended C Style and Coding Standards, Indian Hill C Style and Coding Standards Updated
by authors from Bell Labs, (http://www.cs.huji.ac.il/papers/cstyle/cstyle.html)
f. C coding Guidelines, Real Time Enterprises, Inc. Rev 7, 6/24/96
g. C++ Guidelines (companion document to C coding guidelines), Real Time Enterprises, Inc., Rev
0 11/8/1995
h. C style and Coding Standards for the SDM Project, ROUGH DRAFT, July 3, 1995
(http://www-c8.lanl.gov/sdm/DevelopmentEnv/SDM_C_Style_Guide.hyml
i. Software Design and Coding Standards for C++, Authors Unknown., 7/7/1994
j. C Programming Standards and Guidelines, Internal Document 8/10/93, Software Warehouse
index # 100
k. C++ Style Guide, Internal Document, 6/22/90, Software Warehouse index # 201
l. Using Visual Basic for Applications (Appendix D- Style Guide for Professional Quality Code),
QUE, (ISBN 1-56529-725-3)
m. Speaking the Language of the PM API, Part 4 (Overview of Hungarian Notation), PC Magazine
March 14, 1989)
n. Programming Integrated Solutions with Microsoft Office, Appendix B, Visual Basic Variable
Naming and Coding Standards.
The standards and guidelines described in this document were selected on the basis of common
coding practices of people within our group and from many language specific programming standard
documents collected throughout the company and the Internet. They can’t be expected to be
complete or optimal for each project and for each language. Individual projects may wish to
establish additional standards beyond those given here and the language specific documents. Keep in
mind that sweeping per-project customizations of the standards are discouraged in order to make it
more likely that code throughout a project and across projects adopt similar styles.
This is a list of coding practices that should be standardized for each project, and may require
additional specification or clarification beyond those detailed in the standards documents.
1. Naming conventions:
• What additional naming conventions should be followed. In particular, systematic prefix
conventions for functional grouping of global data and also for names of structures,
objects, and other data types may be useful.
3. File Organization:
• What kind of Include file organization is appropriate for the projects data hierarchy
• Directory structure
• Location of Make Files
(note: “Actions taken before compilation or assembly is performed should be the
directory in which the source code resides, unless otherwise specified.)
5. Revision and Version Control: configuration of archives, projects, revision numbering, and
release guidelines.
7. Standardization of the development environment - compiler and linker options and directory
structures.
• Header files can define global data types constants and macros, and contain external
declarations that is shared between multiple modules.
• Header files will not be used to initialize data
• Do not put any private information in a header file
/*****************************************************************************
1. * Copyright 1999, All rights reserved, For internal use only
*
* FILE:
* PROJECT:
* MODULE:
*
* Description:
*
* Notes:
*
* Compiler dependencies or special instructions:
*
* REVISION HISTORY
* Date: By: Description:
*
*****************************************************************************/
• Exception processing - describe any unusual actions taken by the unit, including its handling of
invalid input data.
• Notes - give commentary on the algorithm, efficiency evaluations, alternative methods, etc.
Note that the purpose of this section is not to provide a general description of the code’s
purpose and structure; this is provided by the Distributed Code Description, as described
below.
• Revision history, included for origin and each set of changes:
- Date of revision
- Name of programmer making change(s)
- Description of change(s), including reasons for change and any other statements of
interest
/**************************************************************************
* NAME:
* Description:
*
* Subroutines Called:
*
* Returns:
*
* Globals:
*
* Designer(s):/ Design Document:
* Programmer(s):
* Tested By: Date:
* Assumptions and Limitation:
*
* Exception Processing:
*
* NOTES:
*
* REVISION HISTORY
* Date: By: Description:
*
**************************************************************************/
4.1 Use constants and macros instead of hard coded literal values
If supported by the language,
• Literal values shall be avoided in code statements; rather, a symbolic constant for each shall be
defined reflecting its intent. 0 should not be assumed to mean “OFF”, a symbolic constant OFF
should be defined to be equal to 0.
• The numeric literals 0 and 1 shall not be used as Boolean constants. Booleans are not to be
treated as integers.
• Whenever different constants must have fixed relationships and whenever allowed by the
language, the fixed relationships shall be forced to hold true. For instance, if ConstantB must be
twice the value of ConstantA, define ConstantB as being equal to 2 * ConstantA.
Wrong:
Correct:
There are times when expected modifiability would dictate that constants be placed in a dependable
area (e.g. in the global header file, etc.) for easy access and changing.
AUTHOR(s): APPROVED: Revised:
• Global data is generally to be avoided. Parameters are the preferred method of communication
among subroutines.
• Limit scope of module-level data to the module (i.e. use the static storage class specifier to
declare functions and data local to the file).
• Any variable whose initial value is important to be initialized should be with executable code,
don’t initialize static data at time of allocation.
6. Subroutines
• If a subroutine parameter list is longer than one line, lines after the first one will be indented
from the left margin so that the second parameter will be listed directly below the first parameter
• The list of the function parameters should have a definite order. The most conventional ordering
of parameters is: Input, modified (input and output), and finally output parameters.
• A function that returns information via one or more of it’s parameters may return only status
information in its name
• For complicated function calls (with multiple parameters) listing each parameter passed on a
separate line with a short comment describing it’s function makes the function easier to
comprehend.
• For complicated function calls, you can use a prefix for each of the parameters to clearly
distinguish input, modify, and output parameters. For example: In_, Mod_, Out_ for input,
modify, and output parameters respectively).
7. Comments
For example:
AUTHOR(s): APPROVED: Revised:
/*
============================
This is an example of a blocked comment that
is easily distinguished from the rest of this document,
and is easily edited.
============================
*/
A comment shall accompany each definition of a constant, type, or variable, giving its purpose. The
comment shall either be on the same line as the definition (to the right), or on the previous line(s).
8. Code Layout
ends of lines, rather than at the beginning of the next line, to make it clear at a glance that more is
coming.
C language example:
Any of the following three are acceptable. Note that the brackets are either considered part of the
conditional statement (first and second example) or part of the resultant functional block (third
example, called a pure-block scheme). Mixing bracket attachment (one part of the conditional, one
part of the functional block, as in the fourth and fifth examples) is discouraged. In example 6, the
bracket is not attached to either the conditional or the functional block.
AUTHOR(s): APPROVED: Revised:
recommended:
if (gTestFlag = = TRUE)
{
Run_Machine_1( );
} /* end if gTestFlag is True */
if (gTestFlag = = TRUE) {
Run_Machine_1( );
} /* end if gTestFlag is True */
if (gTestFlag = = TRUE)
{
Run_Machine_1( );
} /* end if gTestFlag is True */
wrong: first bracket is part of the conditional, but second bracket is part of the functional block.
f (gTestFlag = = TRUE) {
Run_Machine_1( );
} /* end if gTestFlag is True */
wrong again:
f (gTestFlag = = TRUE)
{
Run_Machine_1( );
} /* end if gTestFlag is True */
f (gTestFlag = = TRUE)
{
Run_Machine_1( );
} /* end if gTestFlag is True */
Another STRONGLY SUGGESTED standard is that all functional code following a conditional be
delimited, even a single line. The following example illustrates why... the two lines of functional
code after the conditional appear from indentation to both run. Only the first one does.
wrong:
if (gTestFlag = = TRUE)
Run_Machine_1( );
Write_Timestamp_To_Log( );
if (gTestFlag = = TRUE)
{
Run_Machine_1( );
} /* end if gTestFlag is True */
Write_Tmestamp_To_Log( );
A Hungarian Prefix should be used to identify the return type on functions that return a value:
struct type
{
integer iAddress;
string strLastName;
}
EmployeeDataStruct *EmployeeDataStructPtr; /* struct and pointer to struct name */
EmployeeDataStruct stEmployee;
AUTHOR(s): APPROVED: Revised:
9.6 Use of upper/lower case and underscores to differentiate Subroutines, Variables, and
Constants.
Program-specific identifiers shall be differentiated from reserved words by use of upper/lower/mixed
case; the exact scheme for doing so shall vary with the language, but not from project to project.
Assume that the language that you are programming in, is case insensitive, even if it isn’t (as in C).
This will prevent the creation of variables such as portnum, PortNum, and Portnum, which can in
fact be three different variables performing three different functions... a very difficult thing to figure
out and maintain.
9.8 Variables
Other sorts of identifiers (such as those for types, and variables) shall not contain underscores, and
use upper case for the first letter in each unique word. For example; a Boolean function could be
named “Stack_Is_Updated”, and a Boolean variable with a similar purpose could be named
“StackIsUpdated”. This allows very differentiation between functions and variables. A variable
“Color” can’t be confused with the function “color”.
<<Note C++ exception>>
9.10 Use of prefix (Hungarian) notations to differentiate the scope and type of a data
variable
The Hungarian naming convention is a set of guidelines for naming variables and routines. The
convention is widely used the C and Visual Basic languages. (For the engineering department, a
modified Hungarian notation will be suggested.)
The use of Hungarian Notation is strongly encouraged, but may vary in form on a per-project basis.
If used, prefixes can vary from language to language and across applications. A list of the prefixes
should to be defined as part of the project specific standards. A list of commonly used prefixes that
should be used as a starting point or template for the project’s list will be included below.
AUTHOR(s): APPROVED: Revised:
Strict Hungarian names are composed of three parts: one or more prefixes (i.e. bl for Boolean, a for
array), the base type (i.e. wn for Window, ch for character), and a qualifier (descriptive part of the
name that would probably make up the entire name if you weren’t using Hungarian notation).
Example:
The apch prefix of apchFileSpec means that the variable is an array (a) of pointers (p) to characters
(ch). Just from looking at the variable name you can guess that the variable is defined something like
this:
char *apchFileSpec[10]. And that tells you a lot more about the variable than a simple name
FileSpec.
The following three section are tables of common Hungarian type-defined prefixes:
Type Prefix
Boolean bl, bln
char ch
unsigned char uch
short s
unsigned short us
long l
unsigned long ul
float (or single) f
double d
bit b
byte by
function fn
array a
pointer p
string sz, str
void v
file pointer fp
file descriptor fd
array of characters ach
pointer to a pst
structure
Usage Prefix
State sta
Register reg
Counter ctr
Index idx
Flag flg
Label lbl
Pointer ptr
Object obj
Function fn
Array ary
String str
Void vd
Command cmd
Dialog dlg
Control ctr
Data dat
File fil
Form frm
Graph gra
Image img
Key key
Menu mnu
OLE ole
Picture pic
Report rpt
Timer tmr
Window wnd
Window Handle hwnd
Additional Reading:
• Chapter 9 section 5 of the book “Code Complete” (Refer to References, section 1.5 of this
document) describes the Hungarian naming convention, rules for use, and advantages and
disadvantages.
• Speaking the Language of the PM API, Part 4 (PC magazine, March 14, 1989)
9.11 Abbreviations
An abbreviation shall only be considered if it saves a considerable number of characters (e.g., “FFT”
for “Fast Fourier Transform” is acceptable, but “Snd” for “Send” is not), as long as the language
does to restrict identifier lengths severely. An abbreviation list shall be created during the design
phase of each project. However, smaller groups of programmers may create their own abbreviations
for terms which are used within the domain of the code to which they are assigned; again, the use of
these abbreviations shall be consistent. Any abbreviations which are on the list must be used by all
programmers for any identifiers which include the corresponding phrase. For example, if series of
procedures sends various types of messages using the identifiers Send_Hello_Msg,
Send_Connect_Msg, and Send_Data_Msg, then the name of a new procedure in the series should
not be Send_Disconnect_Message. To do otherwise simply encourages coding errors and frustrates
text searches.
Alignment align
average avg
calibrate calib
calibration calib
channel chn
AUTHOR(s): APPROVED: Revised:
coefficient coef
column col
control cntl
controller cntl
degrees deg
detector det
high hi
length len
low lo
maximum max
message msg
minimum minm
minutes min
number numb
quadrant quad
seconds secs
tolerance tol
unit-under-test UUT
Always test floating-point numbers as <= or >= relational operator, never use exact comparisons (
= = or != ).
No assumptions shall be made about the value of uninitialized variables, unless the language
definition makes a clear statement about this.
if ( gblnTestFlg )
{
do_this( );
} /* end if gblnTestFlg */
Correct:
if ( gblnTestFlg = = TRUE )
{
do_this( );
} /* end if gblnTestFlg */
Interrupt handlers shall perform minimal processing, and shall be meticulously commented.
In high-level languages, multiple exits from a unit are allowed if that avoids excessive control
structure nesting.
When data files are accessed in a tree-structured directory environment, the names of the file
directories shall not be hardwired in the code; whenever possible, environment variables or some
AUTHOR(s): APPROVED: Revised:
similar mechanism shall be used to provide exact directory names dynamically. The same applies to
the names of nodes which are accessed in a network. (see section 5.4 on constants and coding style).
Go-tos are not to be “avoided at all costs”. It is, instead, serpentine code that needs to be avoided.
Simplicity and clarity should override most other design decisions. A go-to, in particular, is a
powerful tool when used as a direct, no-nonsense jump under well-stated conditions, and can very
closely follow problem-space behavior if used with some planning and forethought (Ada, a language
designed from scratch by smart French people, contains a goto keyword). On the other hand, the
indirection of a pointer tends to be a computer-space construct, that is often confusing and - if
honesty should prevail - unnecessary (Java, the latest geek programming language, does not allow
the use of pointers).
10.7 Type casting integer and float variables makes code more portable
If the language allows (as with C’s “typedef” or Ada’s subtypes), all integer and floating types
which are important in the program should be defined as new types within the program. This will
allow for easy correction if the code is ported to a different compiler or machine with different
default work sizes. This also often allows for much better type checking, depending on the
language.
10.9 Use ASCII files for runtime or machine dependent constants and macros
Whenever possible, values which remain static throughout runtime but which can be used to tune or
modify the program shall be read from an ASCII file at the start of runtime, to allow for dynamic
modification without recompilation or relinking. Note that in some cases, the program design may
specify features to support dynamic tuning or modification of some of these values (for example,
machine setpoints).
10.11 Debugging
Rules for i.e. #define DEBUG_MODULE_NAME
It may not be easy to attain low coupling, high cohesion, and clean interfaces at the same time, but
the final product will be cleaner and easier to maintain because of this extra effort.
11.3 Cohesion
Cohesion refers to the relation of the statements within a routine. There are different ways in which
statements can be related. Functional cohesion, which means that the statements perform a single
purpose or goal, is the strongest type of binding and the ideal to strive for.1
11.4 Coupling
Coupling refers to the degree to which two routines are dependent on each other, or the degree of
difficulty one would have trying to change one routine without having to change the other. Data
coupling would depend on the number and type of parameters passed into or out of a routine.
Loose data coupling (low dependence between modules) is the ideal coupling method.1
by a routine), then each routine will be isolated from what happens in other parts of the program.
Each routine can then be tested and debugged and integration should then run smoothly.
Whenever allowed by the language, all constants, types, and variables shall be declared only within
the scope in which they need to be known.
Data items must not be accessed or altered by some obscure process. Data should be local if at all
possible. "Pass through" parameters (or "Tramp Data"), whose only function is to pass data down
to called routines creates readability and maintainability problems. Each data linkage makes
integration problems more probable.2