typical error patterns in c++
DESCRIPTION
Typical Error Patterns in C++. Presented by: Eui-Seok Kim SVD Inc., Seoul, Korea www.svd.co.kr. Unsafe Codes. Arrays & pointers in interfaces void* Variadic functions union Casts Implicit conversions Naked new/delete Why does C++ allow them? Compatibility with C Performance - PowerPoint PPT PresentationTRANSCRIPT
Typical Error Patterns in C++
Presented by:
Eui-Seok KimSVD Inc.,
Seoul, Korea
www.svd.co.kr
Unsafe Codes
Arrays & pointers in interfaces void* Variadic functions union Casts Implicit conversions Naked new/delete
Why does C++ allow them? Compatibility with C Performance Direct access to hardware
Arrays & Pointers in Interfaces
Old-time C programmers using C++ are the heaviest users of arrays and pointers.
No alternative for the C standard library. SPARROW detects various error patterns of this kind. They are evil! Dangling references(?)
void g(){ int* p = new int; int& r = *p; delete p; ++r; // oops!}
void* What is the type of an object pointed by a void*? Co
mpilers have no idea.
Explicit casts are required to convert a void* to another pointer type.
Functions in the C standard library memcpy, memmove, memcmp, memset fread, fwrite malloc, calloc, realloc, free bsearch, qsort
C++ provides more type-safe alternatives.
Variadic functions Compilers cannot check the number and types of para
meters. You're on your own. Functions in the C standard library
printf, scanf Example Original code:
float value; scanf("%e", &value);
The type of value has been changed. double value; scanf("%e", &value); // oops!
C++ provides more type-safe stream classes.
union You have to keep track of current type. Contains POD-type objects only. Example
union U{ int i; char* s;};
void f(U& u) { printf("%s", u.s); }
void g(){ U u; u.i = 0; f(u); // oops!}
Casts "And if you've got a lot of casts in the code, there's s
omething wrong." - Bjarne Stroustrup Pointer and reference casts are evil! Blunt C-style casts: "Shut up, compiler!"
void f(int** a);void g(){ int a[10][10]; f( (int**)a ); // oops!}
Even C++-style casts won't save you much, except that you can locate them easily.
Implicit Conversions
Standard conversions Arithmetic conversion to narrower type Conversion of signed type into unsigned type Conversions between integral and floating-point
type Conversion of string literal into a non-const char*
User-defined conversions Conversion by constructor Conversion functions Should be used with great care (explicit keyword)
Implicit Conversions
Examples
void f(char* s) { s[0] = 'j'; }
void g(){ char* s = "hello"; f(s); // oops!}
const char* str = "hello";int len = -1;assert(strlen(str) > len); // assertion fails!
Implicit Conversions Examples
template <typename T>class Array{public: Array(int size); T& operator[](int); Array<T>& operator=(const Array<T>&); //...};
Array<double> a(10);a[0] = 0; a[1] = 1; a[2] = 4;a[3] = 9; a[4] = 16; a = 25; // oops!
CString s("hello"); // from Microsoft ATL CString classs - "o"; // what the hell is this?
Naked new/delete
Common errors delete'ing new[]'ed memory delete[]'ing new'ed memory double delete'ing delete'ing non-heap memory not delete'ing mixing new/delete with malloc/free checking for NULL after new operation
int* p = new int; // throws std::bad_allocint* q = new(std::nothrow) int; // returns NULL
new/delete: Safety Issues
Evil pointer operations Not exception-safe Memory leakage Use std::vector or std::string instead.
Resource Management: RAII Resource acquisition is initialization Encapsulated Resource-agnostic
memory files sockets locks images…
Deterministic Examples
stream classes in the standard library std::auto_ptr std::tr1::shared_ptr ScopeGuard (http://www.ddj.com/cpp/184403758)
Resource Management: RAII
C Way: What a mess!
C++ Way: RAII
excerpt from http://en.wikipedia.org
Rule of the Big Three A class with a destructor needs…
a copy constructor an assignment operator
Mostly resource-acquiring classes Make it clear if the class is noncopyable.
class MyClass{public: MyClass(int v) : value_(new int(v)) {} ~MyClass() { delete value_; }private: int* value_;};
int main(){ MyClass c1(0); MyClass c2(c1);} // delete twice
Initialization Order in Constructor
Initialization follows the member declaration order, not the initialization order.
template <typename T>class Array{public: explicit Array(int size) : size_(size), capacity_(size_ + 10), data_(new T[capacity_]) { } // ...private: T* data_; int capacity_; int size_;};
Default Arguments
They can lead to unintended results. Things get even worse when used in constructors.
class Point{public: Point(double x = 0.0, double y = 0.0) : x_(x), y_(y) { }private: double x_, y_;};
int main(){ Point p = (1.0, 2.0); // what is the value of p.x_ and p.y_? return 0;}
Arrays and Inheritance struct B
{ B() : i_(0) { } int i_;};
struct D : public B{ D() : j_(1) { } int j_;};
void f(B* pb){ int i = pb[1].i_; assert(i == 0); // assertion fails!}
int main(){ D d[10]; f(d);}
STL containers and iterators Invalid subscript (vector, string, deque) Iterator to an invalidated object
list<int>::iterator f(){ list<int> l; return l.begin();}
void g(){ vector<int> v(2); vector<int>::iterator it = v.begin(); v.reserve(1024);}
Dereferencing a "null" iterator or iterator to the one-past-the-last element
set<int> s; set<int>::iterator in, it = s.find(0); cout << *in; cout << *it;
STL containers and iterators Runaway iterators
list<int> a, b;list<int>::iterator p = find(a.begin(), b.end(), 100);
Iterators to an erased elements list<int>::iterator q = a.begin();
b.erase(q);
Iterators to destroyed containers list<int>* pl = new list<int>; list<int>::iterator p = pl->begin(); delete pl; cout << *p; // oops!
Got enough space?vector<int> u(10), v, w;copy(u.begin(), u.end(), v.begin());copy(u.begin(), u.end(), back_inserter(w)); // ok
STL containers and iterators Iterators are generalized pointers. Most array- or pointer-related issues have iterator cou
nterpart. Iterators don't know the containers they are pointing at.
More Information
Bjarne Stroustrup, The C++ Programming Language Scott Meyers, [More] Effective C++ Scott Meyers, Effective STL Herb Sutter, [More] Exceptional C++ Stephen Dewhurst, C++ Gotchas Bjarne Stroustrup's Homepage
http://www.research.att.com/~bs/homepage.html Herb Sutter's Homepage
http://www.gotw.ca/ C++ FAQ Lite
http://www.parashift.com/c++-faq-lite/