C++ Gotchas: Avoiding Common Problems in Coding and Design
http://www.semantics.org/
Chapter 1: Basics
Gotcha #1: Excessive Commenting
If meaningful and mnemonic names are used in a program, there is ofter only occasional need for additional comments. Follow a simple, well-defined naming convention and choose clear names that reflect the abstract meaning of the entity (function, class, variable, and so on). Formal argument names in declarations are particularly important. The goal is to employ the minimal volume of comments that permits the code to be readily understood and maintained.
Gotcha #2: Magic Numbers (Raw numeric literals)
Raw numeric literals off no advantage and many disadvantages. Use enumerators and initialized constants instead. Enumerators consume no space and cost nothing in runtime while providing clear, properly scoped names of the concepts for which they stand.
Gotcha #3: Global Variables
Avoid global variables. Global variables increase coupling among components, impede code resue and make code hard to maintain. If a function or class guards (One method is to employ Singleton pattern) access to the global information, the setting of the initial value can be delayed until it's safe to do so.
Gotcha #4: Failure to Distinguish Overloading from Default Initialization
Overloading is generally used to indicate that a set of functions has common abstract meaning but different implementations. Default initialization is generally used for convenience, to provide a simplified interface to a function.
Gotcha #5: Misunderstanding References
A reference is an alias for its initializer. The only thing one can do with a reference is to initialize it. After that, it's simply another way of referring to its initializer.A reference doesn't have an address, and it's even possible that it might not occupy any storage. It is illegal to attempt to declare a reference to a reference, a pointer to a reference, or an array of references. No null reference, no references to void. A reference return from a function allows assignment to the result of a call. For example, an index function for an abstract array. Reference may also be used to provide additional return values for functions.
Gotcha #6: Misunderstanding Const
int i = 12; const int *pi = &i; Here const means a restriction on how we may manipulate i through pi rather than on how i may be manipulated in general.
Gotcha #7: Ignorance of Base Language Subtleties
int ary[12]; int *p = &ary[5]; p[2]=7; 2[p]=7; p[2] is entirely equivalent to *(p+2). the addition is commutative and it's legal to index an integer with a pointer: 2[p]=6;
Gotcha #8: Failure to Distinguish Access and Visibility
One way to aviod recompilation is to "forward declare" the class by using an incomplete class declaration in contexts where more information about the class is not required: class C. Such an incomplete declaration will still allow us to declare pointers and references to a C as long as we perform no operations that require the knowledge of C's size or members, including base class subobjects. To avoid maintenance problems, it's important to pick up the incomplete class declaration from the same source that supplies the class definition. We should provide a "forward declaration" header file that supplies an appropriate set of forward declarations. Bridge pattern involves separating the class into two parts, an interface and an implementation.
Gotcha #9: Using Bad Language
There is no way to represent a null pointer directly in C++, but we're guaranteed that the numeric literal 0 is convertible to a null pointer value for any pointer type. real C++ programmers still use 0 to represent the null pointer value.
Gotcha #10: Ignorance of Idiom
class X
{
public:
X (const X &);
X & operater = (const X &);
}
copy operation idiom. copy constructor and copy assignment operator. Both operations take a reference to a constant, and the copy assignment is nonvirtual and returns a reference to a non-const.
The approach taken by the standard auto_ptr is to depart from the copy operation idiom intentionally:
template <>
class auto_ptr
{
public:
auto_ptr(auto_ptr &);
auto_ptr & operator = (auto_ptr &);
private:
T * object_;
};
Here the right side of each operation is non-const. When one auto_ptr is initialized by or assigned to by another, the source of the initialization or assignment gives up ownership of the heap-allocated object to which it refer by setting its internal object pointer to null.
Gotcha #11: Unnecessary Cleverness
It is nearly always preferable to be conventional, clear, and slightly less efficient than unnecessarily clever, unclear, and unmaintainable.
Gotcha #12: Adolescent Behavior
Chapter 2: Syntax
Gotcha #13: Array Initializer Confusion
In general, prefer vector to low-level arrays.
int *ip = new int[12]; // square brackets
std::vector <> iv (12); //parentheses
Gotcha #14: Evaluation Order Indecision
Function argument evaluation is not fixed to a particular order. It's best to minimize side effects in function arguments.
Gotcha #15: Precedence Problems
Most C++ operators are left-associative, and C++ has no nonassociative operators.
int a = 3, b = 2, c = 1;
if(a>b>c) //legal, but probably wrong... the result is false
Gotcha #16: for Statement Debacle
It is generally a good idea to restrict the scope for a variable to the region of the program in which it is used. It is possible to declare a variable in the condition of an if-statement. The variable will be available in the statements controlled by the condtion, both the "true" and "false" branches. The same is true of the for-statement. Under the new semantics, the scope is restricted to the for-statement itself. All for-statements be written to the new semantics is recommended..
Gotcha #17: Maximal Munch Problems
a+++++b is illegal because it's tokenized as a ++ ++ + b, and it's illegal to post-increment an rvalue like a++. In one of the early stages of C++ translation, the portion of the compiler that perfroms "lexical analysis" has the task of breaking up the input stream into individual "words," or tokens. To avoid this ambiguous state of affairs, the lexical analyzer always identifies the longest token possible, consuming as many characters as it legally can: maximal munch.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment