I l@ve RuBoard Previous Section Next Section

Item 47. Control Flow

Difficulty: 6

How well do you really know the order in which C++ code is executed? Test your knowledge against this problem.

"The devil is in the details." Point out as many problems as possible in the following (somewhat contrived) code, focusing on those related to control flow.



#include <cassert> 


#include <iostream>


#include <typeinfo>


#include <string>


using namespace std;





//  The following lines come from other header files.


//


char* itoa( int value, char* workArea, int radix );


extern int fileIdCounter;





//  Helpers to automate class invariant checking.


//


template<class T>


inline void AAssert( T& p )


{


  static int localFileId = ++fileIdCounter;


  if( !p.Invariant() )


  {


    cerr << "Invariant failed: file " << localFileId


         << ", " << typeid(p).name()


         << " at " << static_cast<void*>(&p) << endl;


    assert( false );


  }


}





template<class T>


class AInvariant


{


public:


  AInvariant( T& p ) : p_(p) { AAssert( p_ ); }


  ~AInvariant()              { AAssert( p_ ); }


private:


  T& p_;


};


#define AINVARIANT_GUARD AInvariant<AIType> invariantChecker( *this )





//-------------------------------------------------------------


template<class T>


class Array : private ArrayBase, public Container


{


  typedef Array AIType;


public:


  Array( size_t startingSize = 10 )


  : Container( startingSize ),


    ArrayBase( Container::GetType() ),


    used_(0),


    size_(startingSize),


    buffer_(new T[size_])


  {


    AINVARIANT_GUARD;


  }





  void Resize( size_t newSize )


  {


    AINVARIANT_GUARD;


    T* oldBuffer = buffer_;


    buffer_ = new T[newSize];


    copy( oldBuffer, oldBuffer+min(size_,newSize), buffer_ );


    delete[] oldBuffer;


    size_ = newSize;


  }





  string PrintSizes()


  {


    AINVARIANT_GUARD;


    char buf[30];


    return string("size = ") + itoa(size_,buf,10) +


           ", used = " + itoa(used_,buf,10);


  }





  bool Invariant()


  {


    if( used_ > 0.9*size_ ) Resize( 2*size_ );


    return used_ <= size_;


  }


private:


  T*     buffer_;


  size_t used_, size_;


};





int f( int& x, int y = x ) { return x += y; }


int g( int& x )            { return x /= 2; }





int main( int, char*[] )


{


  int i = 42;


  cout << "f(" << i << ") = " << f(i) << ", "


       << "g(" << i << ") = " << g(i) << endl;


  Array<char> a(20);


  cout << a.PrintSizes() << endl;


}


    I l@ve RuBoard Previous Section Next Section