Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
64 views

Programming Style Guide

C / C++ is free form, placing no significance on the column or line where a token is located. This document illustrates some of the most commonly accepted conventions used in writing "accentless" code. Some header files are supplied with the compiler while others are written to be application specific.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views

Programming Style Guide

C / C++ is free form, placing no significance on the column or line where a token is located. This document illustrates some of the most commonly accepted conventions used in writing "accentless" code. Some header files are supplied with the compiler while others are written to be application specific.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

C/C++ Notes

C/C++ Coding Style Guidelines 1. Introduction

C/C++ Coding Style Guidelines

The C/C++ language is free form, placing no significance on the column or line where a token is located. This means that in the extreme a program could be written either all on one line with token separators only where required, or with each token on a separate line with blank lines in between. Such variations in programming style can be compared to accents in a spoken language. As an accent gets thicker the meaning of the conversation becomes less understandable, eventually becoming gibberish. This document illustrates some of the most commonly accepted conventions used in writing C/C++ programs, providing the consistent guidelines needed to write "accentless" code. 2. File Organization The suggested order for sections of a file is as follows with a blank line placed between each section: 1. A prologue describing what is in the file. This should be a description of the purpose of, not just a listing of, the constructs in the file, whether they be functions, prototypes, external data definitions, macros, or whatever. 2. Header file #include directives 3. Macro #define directives 4. typedefs that apply to the file as a whole 5. External data declarations 6. Function prototypes that apply to the file as a whole 7. Function definitions, in some meaningful order 3. Header Files Header files, usually ending with .h or no extension at all, are files that the C/C++ preprocessor includes in other files prior to compilation as a result of the #include directive. They typically contain such things as the definitions of macros, classes, structures, unions, and inline functions, as well as external data declarations, function prototypes, and typedefs. They should not contain defining function/data declarations or run time program statements and should contain #include directives only as necessary to support the contents of the header file itself. In some applications, typically where multiple C/C++ source files must include many of the same header files, it is acceptable to place all common #include directives in a common header file and include it instead. Some header files are supplied with the compiler while others are written to be application specific. All should be logically organized and each should implement a facility to prevent its multiple inclusion in another file. Header files must be includable any order and must contain Include Guards to prevent multiple inclusions.

1992-2008 Ray Mitchell

1 of 9

C/C++ Coding Style Guidelines 4. Comments

C/C++ Notes

Comments should be used wherever there might be a question about the workings of an algorithm, the purpose of a statement, a macro definition, or anything else that would not be obvious to a programmer unfamiliar with the program. It should never be necessary to "reverse-engineer" a program. Comments should explain algorithmic operations, not semantics. For example, an appropriate comment for the statement distance = rate * time; might be "position of projectile", while something like "multiply rate by time and assign to distance" says nothing useful. With a wise choice of identifiers much code can be made somewhat self-documenting, thereby reducing the need for as many comments. The C++ style of comment, which begins with //, should not be used in C-only programs to avoid backward compatibility problems. The format of a comment is normally determined by its length. Comments occupying more than one line, such as a file prolog or the description of an algorithm, should be in block comment form. Except for partial-line comments, comments should be placed prior to and aligned with the code they comment as follows: A C style block comment (also acceptable in C++): /* * Use a block comment whenever comments that occupy more than one line are needed. Note * the opening / is aligned with the code being commented, all asterisks are aligned with each * other, and that all comment text is left aligned. */ for (nextValue = getchar(); nextValue != EOF; nextValue = getchar()) An equivalent C++ style block comment: // // Use a block comment whenever comments that occupy more than one line are needed. Note // the opening / is aligned with the code being commented, all // are aligned with each other, and // that all comment text is left aligned. // for (nextValue = getchar(); nextValue != EOF; nextValue = getchar()) C and C++ style full-line comments: /* This is a full line C style comment. */ // This is a full line C++ style comment. for (nextValue = getchar(); nextValue != EOF; nextValue = getchar()) It is possible to over comment a program to the point of making it unreadable. This is especially true when code lines and comment lines are intermixed. Many comments can be reduced to the point of being small enough to fit to the right of the code being commented while still conveying meaning. To be most readable code should reside on the left side of a page with comments on the right, opposite the code they comment. Whenever possible all such comments should start in the same column as each other, as far to the right as possible. Deciding on the appropriate column is a compromise and there will usually be exceptions in any given program. Using tabs instead of spaces when positioning such comments reduces the effect of making minor code changes but may not be interpreted correctly by the printer. The following illustrates these "partial-line" comments: while ((nextValue = getchar()) != EOF) { if (nextValue == '.') break; else ++charCount; } 1992-2008 Ray Mitchell /* while source file has characters */ /* got sentence terminator */ /* don't read any more characters */ // must continue reading sentence // update characters read in sentence 2 of 9

C/C++ Notes

C/C++ Coding Style Guidelines

The following examples use exactly the same code but with the comments (if any) placed differently. Which programmer would you hire? WRONG while ((nextValue = getchar()) != EOF) { if (nextValue == '.') break; else ++charCount; } --------------------------------------------------------------------------------------------------------------------------------WRONG while ((nextValue = getchar()) != EOF)/* while source file has characters */ { if (nextValue == '.')/* got sentence terminator */ break; /* don't read any more characters */ else/* must continue reading sentence */ ++charCount; /* update characters read in sentence */ } --------------------------------------------------------------------------------------------------------------------------------CLUTTERED ??? /* while source file has characters */ while ((nextValue = getchar()) != EOF) { /* got sentence terminator */ if (nextValue == '.') /* don't read any more characters */ break; /* must continue reading sentence */ else /* update characters read in sentence */ ++charCount; } --------------------------------------------------------------------------------------------------------------------------------EASY TO READ while ((nextValue = getchar()) != EOF) { if (nextValue == '.') break; else ++charCount; } /* while source file has characters */ /* got sentence terminator */ /* don't read any more characters */ /* must continue reading sentence */ /* update characters read in sentence */

1992-2008 Ray Mitchell

3 of 9

C/C++ Coding Style Guidelines 5. Literals

C/C++ Notes

A "magic number" is defined as a numeric literal (and in some cases a character or string literal) embedded in a programs code or comments. They make programs cryptic and difficult to maintain because their meaning is not obvious and, if they must be changed, the likelihood of missing one or changing the wrong one is high. There are a few cases, however, where magic numbers are acceptable, including: 0 & 1 as array indices or loop start/end values, 1 as an increment/decrement value, 2 as way to double/halve a value or as a divisor to check for odd/even, coefficients in some mathematical formulae, some print strings, cases dictated by common sense In general, however, the #define directive (in C), const-qualified variables (in C++), or enumerated data (C and C++) should be used to associate meaningful names with literals. This permits values to be changed everywhere in a program by making a change in only one place. Avoid, however, the pitfall of choosing names that reflect the value they represent, such as #define SIX 6. This is as bad as directly coding 6 itself. Would you ever define SIX to be anything other than 6? Because the constant macro NULL (as defined in the standard header files) may be implemented as (void *)0, it must never be used in other than pointer contexts. 6. Naming Conventions 1. Choose meaningful names that reflect usage whenever possible and practical. 2. Function and function-like macro names should be verbs; all other names should be nouns. 3. To avoid conflicts with internal names, leading or trailing underscores should be avoided in application programs. 4. Object-like macro, const-qualified variable, and typedef names should be in upper case. 5. Function, function-like macro, and class/struct/union/enum tag names should be in Pascal case (i.e., PascalCaseName). 6. All other names should be in camel case, (i.e., camelCaseName). 7. Compound Statements A compound statement is defined as a brace enclosed series of zero or more statements (which may include other compound statements). For clarity one blank line should separate the declarations from the other statements but blank lines should not be used excessively or arbitrarily. To avoid confusion, don't use declarations that hide variables already in scope. Compound statements may be placed anywhere simple statements may but are required for the bodies of functions and switch statements. They are also used as the statement part of if, else, for, while, and do constructs if more than one simple statement must be associated with that construct. Note that a compound statement is often not used if a simple statement will do, that is: Yes for (...) velocity = 1; acceleration = 2; No for (...) { velocity = 1; } acceleration = 2;

Although they are also brace enclosed constructs, data template definitions and initializer lists are not compound statements.

1992-2008 Ray Mitchell

4 of 9

C/C++ Notes
8. Placement of Braces { }

C/C++ Coding Style Guidelines

A point of contention among some C/C++ programmers is the placement of the braces associated with compound statements, data template definitions, and initializer lists. Two popular formats are: Opening and closing braces always on their own lines, except for the while part of a do loop. Opening brace on the same line as its associated construct unless the construct is a function definition; closing brace on its own line unless the construct continues. Examples of the two formats are shown side by side. Choose one (not your own variation of it) and use it exclusively and consistently. Do not intermix the two. Unlike the examples below, if only one declaration or statement is used the braces are usually omitted: if (...) if (...) { { declarations/statements declarations/statements } else if (...) { } declarations/statements else if (...) } else { { declarations/statements declarations/statements } } else { declarations/statements } --------------------------------------------------------------------------------------------------------------------------------for or while (...) for or while (...) { { declarations/statements declarations/statements } } --------------------------------------------------------------------------------------------------------------------------------do do { { declarations/statements declarations/statements } while (...); } while(...); --------------------------------------------------------------------------------------------------------------------------------switch (...) switch (...) { { declarations declarations case ... : case ... : statements statements break; break; } } --------------------------------------------------------------------------------------------------------------------------------int SomeFunction(void) int SomeFunction (void) (Both forms are the same!) { { declarations/statements declarations/statements } } --------------------------------------------------------------------------------------------------------------------------------struct or union or enum tag struct or union or enum tag { { declarations declarations }; }; -------------------------------------------------------------------------------------------------------------------------------- 1992-2008 Ray Mitchell 5 of 9

C/C++ Coding Style Guidelines

C/C++ Notes
double factors[] = { initializer, initializer, ... };

double factors[] = { initializer, initializer, ... };

An acceptable variation of either format occurs when an initializer list or data template is short and everything will fit on the same line, as in: double factors[] = { initializer, initializer, ... }; 9. Indenting Indenting is a visual tool used strictly to enhance a program's human readability and is totally ignored by the compiler. An indent signifies the association of one or more statements with a previous, less indented construct, as in the following examples: if (...) { x = 1; printf(...); } else if (...) z = y; else { int t = 2; ++v; } The rules for how and when to indent are simple: 1. Braces must be aligned according to the placement formats previously discussed. 2. All declarations and statements associated with a construct must be indented equally from the left edge of that construct. 3. The width used for all indents must be consistent throughout any program. One final consideration is the width of each indent. The normal width of a tab stop is 8 spaces. For most programs this is too wide and the program ends up going off the right edge of the screen or wrapping around. An indent width of 3 spaces is recommended. Widths smaller than 3 tend to be hard to discern while larger values run out of screen space. Actual spaces should be used rather than modifying the editor's tab stop value. This is because the system printer usually has no way of knowing the editor's tab setting and will assume it is 8, giving a garbled program listing. for (...) while (..) { x = 2; ++d; } do { y = 3; x = y + 9; } while (...); int main(void) { int ch = 'A'; putchar(ch); return EXIT_SUCCESS; }

1992-2008 Ray Mitchell

6 of 9

C/C++ Notes
10. Multiple Statements On One Line

C/C++ Coding Style Guidelines

Do not put more than one statement on a line. Similarly, put the body of an if, else, for, while, do, or case on the next line. Chained assignments such as x = y = z = 0; are permissible as long as all operands are logically related. Multiple variables of the same type may be declared on the same line, comma separated, unless a comment is required. The following examples illustrate some acceptable and non-acceptable formats: Do Don't

x = 5; x = 5; y = printf(...); Delete(); y = printf(...); Delete(); --------------------------------------------------------------------------------------------------------------------------------for (idx = 0; idx < MAX; ++idx) for (idx = 0; idx < MAX; ++idx) printf("%d", idx); printf("%d", idx); --------------------------------------------------------------------------------------------------------------------------------if (y < x) if (y < x) printf("%d\n", x); printf("%d\n", x); else printf("%d\n", y); else printf("%d\n", y); --------------------------------------------------------------------------------------------------------------------------------case 'A': case 'A': putchar('A'); break; (See below) putchar('A'); break; A common exception is where multiple switch cases are almost identical. Readability may actually be enhanced by grouping them as: case 'A': case 'B': case 'C': case 'D': putchar('A'); putchar('B'); putchar('C'); putchar('D'); break; break; break; break;

11. The "else if" Construct If an if follows an else, separated by only whitespace, the if should be placed on the line with the else, thereby forming the standard C/C++ "else if" construct. Do if (a > b) ++a; else if (a < x) ++b; 12. Functions Each function definition should be preceded by a block comment prologue that gives its name and a short description of what it does. A function's return type must always be specified and never defaulted to type int by omitting it. Functions not returning a value must use the keyword void. Placing a return type on its own line in column 1 is common. Formal parameters must be declared using the ANSI standard format and C functions with no parameters must use void in place of the parameter list. Although C++ functions with no parameters may also use void for this purpose, it is more common to leave their parameter lists empty. 1992-2008 Ray Mitchell 7 of 9 Don't if (a > b) ++a; else if (a < x) ++b;

C/C++ Coding Style Guidelines

C/C++ Notes

Either the definition of a function or its prototype must visible to the caller before the function is called. Explicitly declaring a function as external by using the keyword extern is obsolete. Prototypes for user functions needed by more than one file and all library functions, such as those in the standard C/C++ library, must be kept in header files that are included by any files needing them. Do not by duplicate the prototype in each file. In multi-file programs all functions not shared with other files should be declared static to limit their scope. 13. External Variables Referencing declarations of external variables used by more than one file must be kept in header files that are included by any files needing them. Do not by duplicate the declaration in each file. In multi-file programs, all external variables (except const-qualified external variables in C++) not shared with other files should be declared static to limit their scope. 14. Automatic Variables If initialization is required, automatic variables should be initialized as close to the point of use as is practical. A program that initializes automatic variables when declared but doesn't use them until much later is difficult to read. Depending upon the operating system, the use of extremely large automatic objects (i.e., arrays/structures/classes/unions) can cause compiler/run-time problems due to the amount of stack space required, and initializing such objects can result in significant run time overhead. Making such objects static can sometimes solve these problems but can also result in more overall memory usage. For similar reasons, functions should avoid the arbitrary passing/returning of aggregates. Instead, use pointers or references to them. 15. Operators All ternary and binary operators except class/structure/union member operators should be separated from their operands by spaces. 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, for example: if (x=y && 6<t || ++p) Spaces should be placed after, but not before, all commas and semicolons. They should also be placed after keywords that are followed by expressions in parentheses, with the exception of sizeof and return. On the other hand, macros with arguments must not and function calls should not have a space between the name and the left parenthesis. Unary operators should not be separated from their single operand. Compound assignments and pre/post increment/decrement expressions should always be used instead of their equivalent longer forms. The shorter expressions are evaluated as is and are not expanded to the longer forms. Parentheses around the entire right side of such expressions are not needed, as the following illustrates: Don't Do x += 2 x++ or ++x x >>= 2 x /= 3 + y x=x+2 x = x + 1 or x += 1 x = x >> 2 x = x / (3 + y) or x /= (3 + y)

1992-2008 Ray Mitchell

8 of 9

C/C++ Notes
16. Portability Beware of making assumptions about: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. The number of bits in a data type Byte ordering (big endian vs. little endian) Bit field ordering (left-to-right vs. right-to-left) The size of different pointer types The compatibility of pointers with arithmetic types The internal representation of negative integral numbers The internal representation of floating point numbers

C/C++ Coding Style Guidelines

The operation of a right shift on negative integral numbers (arithmetic vs. logical) The padding of classes/structures/unions The machine's character set (ASCII, EBCDIC, etc.) The evaluation of expressions having side effects when used as macro arguments The order of evaluation of expressions not involving sequence point operators, including expressions used as function arguments

1992-2008 Ray Mitchell

9 of 9

You might also like