From: stanl@cbnewsm.cb.att.com (stanley.b.lippman)
Subject: errata -- c++ primer
Organization: AT&T
Date: Fri, 22 Jan 1993 22:23:32 GMT


here an electronic errata list for the
C++ Primer reflected in the 7th printing

let me once again thank the many people who 
have taken the time to note erors ( :-) ) 
and send them on to me.

And let me once more very humbly apologize  
for my errrors and the consternation they 
may have caused.

stan lippman
at&t bell laboratories
sbl\@research.att.com

*********************************************************

Note:  I will place this (and earlier errata) under the
       directory AW/Primer on 

	   world.std.com

       both the C++ Primer code and errata will then be
       available via anonymous ftp thanks to Addison-Wesley.

       ps: in answer to a post, no, there is no answer
	   set.  sorry.

*********************************************************

Chapter 0:  Getting Started
            (on the wrong foot ...

page 1:  Last paragraph should read ``Items 1, 2, and 4 ...''
         rather than ``Items 1, 3, and 4 ...''

page 1:  Listing should read ``3a.... 3b.... 3c....'' 
	 rather than ``2a.... 2b.... 2c....''

page 2:  First sentence, again: 3a, 3b, 3c, not 2a, 2b, 2c.

-------------------------------------------------------------

Chapter 1: Section 2.5: Increment and Decrement Operators

page 75: Bottom of the page, Stack::~Stack()

	 	delete [] array;

        Note: the importance of using

          	delete [] pointer

       is to insure that when pointer addresses an array of class objects,
       the compiler applies the destructor of that class to each element
       prior to freeing the memory (generally through a direct call of
       `free'.
      
       thus, for non-class type arrays, old c++ers never actually did use
       the [], which back when required an explicit dimension.  old habits
       die hard -- particularly because they __look__ right.
      
       of course, there is no guarantee that

		int *pi = new int[ 10 ];
		// ...
		delete pi;

       will always be safe across all implementations and so good style
       says that the bracket pair should always be used, particularly 
       since the introduction of templates, where forms such as
      
          	T *pi = new T[ 10 ];
          	// ...
          	delete pi;

        would be seriously wrong if T were instantiated with a class type.

-------------------------------------------------------------

Chapter 3: Section 3.11: Free Store Allocation

page 146: more `delete []' emendation:

		delete [] oldia;

---------------------------------------------------------------

Chapter 4: Section 4.1: Resolving an Overloaded Function Call

page 170:  Last paragraph:

	   ``Matching can be achieved in on of __four__ ways ...

	   Note: In the first edition of the Primer, I had combined exact
	   match and promotion, so there had only been three.  In the
	   second edition, breaking out promotions seemed to clarify things
	   (some what, anyway :-)

---------------------------------------------------------------------

Chapter 5: Section 5.7: Class Member Pointer

Note:  Cfront permits

		int (X::*pf)() = X::f;

       and treats it as the equivalent of

	        int (*pfi)() = f;

       In the ARM, however, all instances of 
       taking the address of a class member function
       use the address-of operator:

	        int (X::*pf)() = &X::f;

       An admittedly quick reading of the ARM didn't
       dislodge me of the notice that the two forms
       of initializing `pf' are equivalent.  A note
       from Bjarne, however, did:

       ``Only &X::f yields a pointer to member (see ref man
	under &).  The reason is that in a member function
	of X, X::f means this->X::f, and I didn't want X::f
	to mean one thing in one context and something
	radically different in another.''

        I'd like to thank Chris Skelley for pointing this
	out to me.  Again, at least through 3.*, cfront
        accepts both forms and handles them as equivalent.

page 251:  ps_Screen = &Screen::width;
page 252:
	   int (Screen::*pmf2)() = &Screen::getHeight;

	   pmf2 = &Screen::getWidth;

           typedef Screen& (Screen::*Action)();

	   Action deFault = &Screen::home;
	   Action next = &Screen::forward;

page 253:

	   Action deFault = &Screen::home;

	   action( Screen&, Action = &Screen::display );

	   void ff() 
	   {
		
		// ...
		action( myScreen, &Screen::bottom );
	   }

page 254:

	   int (Screen::*pmfi)() = &Screen::getHeight;
	   Screen& (Screen::*pmfS)(Screen&) = &Screen::copy;


page 255:

	   Class Screen {
	   public:
		Screen &repeat(Action=&Screen::forward,int=1);
		// ...
	   };

	   myScreen.repeat( &Screen::down, 20 );
	 
	   Action Menu[] = {
		&Screen::home,
		&Screen::forward,
		&Screen::back,
		&Screen::up,
		&Screen::down,
		&Screen::bottom
	    };

page 257:

	  // not double (CoOp::*pf)()
	  double (*pf)() = &CoOp::getCost;

-----------------------------------------------------------------------

Chapter 6: Section 6.3: Operator Overloading

page 311: bottom example of overloading operator>>

	// Note: comment had read:( ostream&, char* );  
	io >> inBuf; // operator>>( istream&, char* );

page 319: again in bottom example, in comment

	// wd1.name.String::operator=( wd2.name );

	Note: comment had read: // wd.name ...

------------------------------------------------------------------------

Chapter 7: Section 7.4: Template Class Specialization

page 368:  last example: a real bug -- sorry

	   #include <string.h>  /* had read: <string.h.

	   typedef char *p_char;
	   QueueItem<p_char>::QueueItem( const p_char& )

           Note: 
	   in the earlier example, the signature had not 
	   exactly matched, and the compiler correctly complained:

		 QueueItem< char* >::QueueItem( char* )	

           unfortunately, cfront 3.* barfs on the inline definition
	   of the specialized constructor -- but that is a bug -- 
	   the corrected example is, well, correct.


Chapter 7: Section 7.9: A Template Array Class

Note:   Tom Cargill pointed this out to me, for which I thank him.
	It comes from brainlessly transcribing code written for an
	integer class -- 

Page 382:  the original code for init() was as follows:

	template <class Type> void
	Array<Type>::init(const Type *array, int sz)
	{
    		ia = new Type[size = sz];
    		assert( ia != 0 );

    		for (int ix = 0; ix < size; ++ix)
         		ia[ix] = (array!=0) ? array[ix] : (Type)0;
	}

        for a class type, such as String, this had the unfortunate
	inefficiency of 
		a. applying String() to each element of the array
		b. converting each (String)0 to a temp by String(int)
		c. applying the memberwise copy operator

	ugh!!!!!!  

        the revised line is:

		ia[ ix ] = array[ ix ];

        with the default Array ctor of page 381 rewritten from

		 Array(int sz=ArraySize) { init(0,sz); }

	to

		 Array(int sz=ArraySize) { 
			ia = new Type[ size = sz];
			assert( ia != 0 );
		 }

	also, on page 382, Array<Type>::grow(),
	the line

		for (; i < size; ++i) ia[i] = (Type)0;

	has quietly been removed and

		delete [] oldia;

	replaces

		delete oldia;

------------------------------------------------------------------------------

Chapter 8: Section 8.3: Base Class Initialization

page 404:  the initialization of Bear in Panda's member initialization
           list is missing an argument:

		Bear( "Ailuropoda melaoleuca",
		      "Panda", 0, PANDA, MIOCENE )

           Note: if I ever do a Third Edition, I think I'll put this
	   example to rest ...

---------------------------------------------------------------------------------

Chapter 10: Object-Oriented Design

page 522, in the Templ_Buf::reset_template() psuedo-code example,
          it should read

		def = t;

-----------------------------------------------------------------------------------

Appendix A: Section A.9: Format State:

page 565:

	last paragraph now reads:

	``By default, a floating point value has a precision value of 6
	(for values between 10 and 99, for example, the decimal point and
	four digits of precision are printed). ...




       



         	
 
Newsgroups: comp.lang.c++