c traps and pitfalls for c++ programmers

21
C TRAPS AND PITFALLS FOR C++ PROGRAMMERS

Upload: richard-thomson

Post on 23-Dec-2014

532 views

Category:

Software


4 download

DESCRIPTION

C++ provides backwards compatability with C, but you will have an easier time if you stay away from certain C-style programming habits. This presentation outlines traps and pitfalls from C style programming in C++ and recommends pure C++ alternatives that lead to fewer surprises, fewer errors and better code. This presentation hasn't been updated for C++11 and is based on C++03.

TRANSCRIPT

Page 1: C traps and pitfalls for C++ programmers

C TRAPS AND PITFALLS FOR C++

PROGRAMMERS

Page 2: C traps and pitfalls for C++ programmers

void *pointers

Loses all type information!

Should be avoided when possible

Make the C++ type system work for you, don’t subvert it

Interfaces to C libraries may require it

Page 3: C traps and pitfalls for C++ programmers

C Style Casts

C style casts:do not communicate the intent of the castcan give the wrong answer

Use relevant C++ casting operatorcommunicates the intent of the castgives the right answer

Use constructor syntax for valuesint(floatFn()) instead of (int) floatFn()

Page 4: C traps and pitfalls for C++ programmers

const_cast<T>(expression) const_cast<T> changes the const or

volatile qualifier of its argument With T const *p

use const_cast<T*>(p) instead of ((T *) p) Declare class members mutable if they

need to be updated from a const method Writing through a reference or pointer

stripped of its constness may cause undefined behavior!

Page 5: C traps and pitfalls for C++ programmers

static_cast<T>(expression) Converts to type T, purely based on the

types present in expression. Use static_cast<T> when:

you intend that the cast does not require any run-time type information

Cast enums to a numeric type (int, float, etc.)Cast from void pointer to T pointerCast across the class hierarchy with multiple

inheritance; see http://www.sjbrown.co.uk/2004/05/01/always-use-static_cast/

Page 6: C traps and pitfalls for C++ programmers

dynamic_cast<T>(expression) Requires RTTI to be enabled Only for pointers or references Returns 0 when object is not a T Resolves multiple inheritance properly

Page 7: C traps and pitfalls for C++ programmers

reinterpret_cast<T>

The most evil of cast operators Subverts the type system completely Should only be needed when dealing

with C style APIs that don’t use void pointers

Page 8: C traps and pitfalls for C++ programmers

Memory Allocation

Any call to new or new[] should only appear in a constructor

Any call to delete or delete[] should only appear in a destructor

Encapsulate memory management in a class

Page 9: C traps and pitfalls for C++ programmers

More on new and delete new/new[]

does’t return 0 when memory is exhaustedthrows bad_allocVC6 did it wrong; VS2005/gcc does it rightNo need to check for zero pointer returned

delete/delete[]Deleting a zero pointer is harmlessNo need to check for zero pointer before calling

Always match new[] with delete[] and scalar new with scalar delete

Page 10: C traps and pitfalls for C++ programmers

Resource Acquisition

Memory is just one kind of resource Others:

critical sectionthread locketc

Treat identically to memory:acquire resource in c’torrelease resource in d’tor

RAII – Resource Acquisition Is Initialization

Page 11: C traps and pitfalls for C++ programmers

Exceptions

Using RAII gives you exception safe code for free

Manual management of resources requires try/catch blocks to ensure no memory leaks when an exception is thrown

Page 12: C traps and pitfalls for C++ programmers

std::auto_ptr<T>

Takes ownership of whatever pointer assigned to it

~auto_ptr() calls delete on the pointer release() returns the pointer and releases

ownership Calls scalar delete; doesn’t work for arrays Use for temporary buffers that are

destroyed when going out of scope or are explicitly assigned to something else on success

Page 13: C traps and pitfalls for C++ programmers

std::vector<T>

Dynamically resizable array Great for fixed-size buffers you need to

create for C APIs when the size of the buffer is determined at runtime.

Use for temporary arrays of objects If used as an array of pointers, it doesn’t

call delete on each pointer

Page 14: C traps and pitfalls for C++ programmers

boost::shared_ptr<T>

Reference counted pointer When reference count reaches zero,

delete is called on the underlying pointer Doesn’t guard against cycles Can be good when used carefully, but

can be bad when used excessively. It becomes hard to identify the lifetime of resources

See boost docs for more

Page 15: C traps and pitfalls for C++ programmers

boost::ptr_vector<T>

Boost container similar to std::vector<T>, but calls delete on each element when it is destroyed

See boost docs for more

Page 16: C traps and pitfalls for C++ programmers

C style strings Don’t use them! Huge source of bugs. Use a string class:

Qt’s QStringC++ std::stringC++ std::basic_string<TCHAR>wxWidgets wxString

Pass string classes by const reference Return string classes by value or through

reference argument Use std::string::c_str() to talk to C APIs

Page 17: C traps and pitfalls for C++ programmers

Use of void

Don’t use void argument lists:Use void foo() instead of void foo(void)

Don’t use void pointersIt completely subverts the type system,

leading to type errors

Page 18: C traps and pitfalls for C++ programmers

Callbacks C code can only call back through a function

pointer. A void pointer context value is usually passed along to the callback

C++ code uses an interface pointer or reference to communicate to its caller. No need to supply a context value as the interface pointer is associated with a class that will hold all the context.

Use interfaces instead of function pointers for callbacks

Page 19: C traps and pitfalls for C++ programmers

#define Use enums to define groups of related

integer constants Use static const class members to define

integer or floating-point values. Declare them in the .h, define them in the .cpp

Use inline functions or methods for small blocks of repeated code

Use templates as a way to write type safe macros that expand properly or generate a compiler error

Page 20: C traps and pitfalls for C++ programmers

Static Polymorphism

Static polymorphism exploits similarities at compile time

Dynamic polymorphism exploits similarities at runtime

Static polymorphism implemented with templates

Dynamic polymorphism implemented with virtual methods on classes

Page 21: C traps and pitfalls for C++ programmers

#if, #else, #endif

Used to express static variation in code When compiled one way, you get one

variation; when compiled the other way, you get the other variation

Better expressed through a template class that expresses the two variations as specifics of arguments to the template

Keeps syntactic checking on for both variations all the time