FAQ 10.10 What can be done to ensure that an object doesn t get blown away by a wild pointer?

FAQ 10.10 What can be done to ensure that an object doesn't get blown away by a wild pointer?

Empower the object to test its invariant at the beginning of every public: member function and every friend function (see FAQ 19.05).

Wild pointers can corrupt a sleeping object. Wild pointers are the SCUD missiles of the software world they are undirected terrorist instruments that wreak havoc in chaotic ways. Once a wild pointer has scribbled on an object, the object also exhibits chaotic behavior, often developing wild pointers of its own. The chain reaction spreads like a virus each wild pointer infects a few more objects. Eventually one of the wild pointers attempts to scribble on something protected by the hardware and then the system crashes.

Once this chain reaction has occurred, programmers must rely on intuition and blind luck when looking for the root cause of the problem. We call this voodoo debugging, since it is about as effective as a fortune teller reading chicken entrails indeed, the technology of reading entrails is remarkably similar to that of reading a core dump after corruption by wild pointers.

An object can help detect wild pointers by beginning all its public: member functions with a call to testInvariant(). This ensures that the object is still in a consistent state.

 #include <cassert> using namespace std; class Date { public:   Date() throw();   Date& operator++ () throw();   int month() const throw();   int day()   const throw();   int year()  const throw(); protected:   void testInvariant() const throw();   int month_;   int day_;   int year_; }; inline void Date::testInvariant() const throw() {   assert(day_ >= 1 && day_ <= 31);   assert(month_ >= 1 && month_ <= 12); } Date::Date() throw() : month_(7) , day_  (4) , year_ (1776) {   testInvariant();                                   <-- 1 } int Date::month() const throw() {   testInvariant();                                   <-- 2   return month_; } int Date::day() const throw() {   testInvariant();                                   <-- 3   return day_; } int Date::year() const throw() {   testInvariant();                                   <-- 4   return year_; } Date& Date::operator++ () throw() {   testInvariant();                                   <-- 5   // ...                                             <-- 6   testInvariant();                                   <-- 7   return *this; } 

(1) public: constructors must establish the invariant

(2) Wild pointers can corrupt a sleeping object.

(3) Wild pointers can corrupt a sleeping object

(4) Wild pointers can corrupt a sleeping object

(5) Wild pointers can corrupt a sleeping object

(6) Put code to increment the date here

(7) public: mutators must maintain the invariant

Since the assert(...) statements within the testInvariant() member function vanish when the symbol NDEBUG is defined, and since the testInvariant() member function is defined using the inline keyword, all the calls to testInvariant() will vanish when NDEBUG is defined. Normally it is not necessary to define the symbol NDEBUG until fairly late in the software development cycle, and some projects (particularly business applications that are not CPU bound) leave it on even after the software is deployed to its users.



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net