Scott Meyers

Modification History and Errata List for Effective C++, First Edition

Last Updated September 2, 1997
by Scott Meyers

Note: This document applies to only the first edition of Effective C++. Errata for earlier editions of the book are available as follows:

What follows is a list of the substantive changes I made to the first edition of Effective C++ between printings. It is not a comprehensive list of modifications, because I also fixed glitches in typesetting, spacing, spelling, etc., none of which affected the technical content of the book.

To use this list, find out which printing of the book you have (it's listed on the copyright page near the bottom), then go to the appropriate section of the list and read from that point forward. For example, if you have a copy of the fifth printing, the changes made to the first four printings won't apply to you, because the changes will already be in place in your copy of the book.

I continue to be interested in bug reports and suggestions for improvements to the book, but future updates will be made to only the second edition of Effective C++. To submit comments, send email to or write to the address listed on page xiii of the book's preface.

The following changes were made between the first and second printings. You need to worry about these changes only if you have a copy of the first printing of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------
  6, 7    All the String constructors taking char* arguments should take
  15, 19  const char* arguments instead.
  34, 48  
  55, 69  
  74, 76  
  97, 99  

  14      Note that the ANSI committee is developing a standard for iostreams.

  19      The results of calling delete on an array w/o the brackets is
          ALWAYS undefined.  The book says it's okay, but only the first
          element in the array will be destructed.  This is wrong twice on
          this page.

  19      "and second, more constructors" ==> "and second, one or more

  24      "::new X;" ==> "::new char[size];"  I added a forward reference to
          Item 8, where the reason for calling new char is explained.

  25      currentHandler should be initialized once per loop iteration, not once
          per function call.  I moved the initialization of currentHandler
          inside the loop.

  28      In the inline op new, "::new X" ==> "new char[size]" 

  33      The void* pointer should be cast back to a char*, since new
          returned a char*.  Hence "::delete [] ((char*) deadObject);"

  46      At bottom of page, "delete ap" should be "delete pa" 

  67      Default value for denominator in class Rational should be 1, not 0.

  129     "Finally, we come to Airplane's nonvirtual" ==>      
          "...we come to Shape's nonvirtual"

  149     The default op= DOES call op= in base classes, so the user does
          not have to write his/her own.  That is, the default op= behaves
          similarly to the default copy constructor.

  160     "five different addresses" ==> "four different addresses"

  164     The text says that RealPerson inherits from Person.  This is not true;
          MyPerson inherits from Person.  I rewrote the paragraph to 
          improve the explanation.

  165     The text fails to explain why RealPerson's functions are
          protected.  This is because it's designed for use only as a base
          class; see also Item 41.

  173     The discussion of the default copy constructor and assignment operator
          makes no mention of what happens in an inheritance hierarchy.
          Basically, the same thing happens at every level of the hierarchy.

  187-8   The throw/catch clauses should take a const char*, not a char*.

  202     Add index entries for "member functions: protected"  and
  204     "protected member functions" for pages 127, 148-9, 156, 165.

The following changes were made between the third and fourth printings. You need to worry about these changes only if you have a copy of one of the first three printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------
  5       "declare arrays of objects"    ==> "define arrays of objects"
          "declare an array of pointers" ==> "define an array of pointers"
          "declaration of B"             ==> "definition of B"

  6       In operator+, insert "delete [];" after declaring temp and
          before assigning to  Otherwise there is a memory leak.

  15      To the list of books describing the iostream library, add 
          "C++ Programming and Fundamental Concepts," Arthur E. Anderson
          and William J. Heinze, Prentice Hall, 1992.

  31      In the code for Airplane::operator new: "new char[" ==> "::new char["

  37      It's not true that matching [] in new and delete is unimportant for the
          built-in types like char.  Omit "In the case of an object type
          ... but in general".

  47      "linker will complain" ==> "linker will probably complain" 

  67      Rational::operator* should be declared a const member function.

  68      The text at the top of the page implies that the compiler looks
          for an operator member function BEFORE searching the global
          scope, but in fact it searches both scopes simultaneously (see
          ARM p.  333).  I reworded things slightly.

  84      The cross-reference at the end of the first paragraph should be
          to Item 31, not Item 29.

  86      "The default constructor has to perform..." ==> 
          "The constructor taking an int has to perform" 

  87      "const void *NULL" ==> "const void * const NULL"      

  88      At the bottom of the page, all the NULL pointers should be const
          pointers to const.

  95      Omit trailing semicolon from macro definition for TRUE.

  95      "costs" ==> "is likely to cost"                       

  107     "enumerators are ints," ==> "the representation for an enumerator
          need not be any larger than that for an int,"

  109     2nd paragraph: the language states that inline functions have
          internal linkage, so compilers MUST treat inlines as if they'd
          been declared static.

  111-2   All the member functions returning char* should return const char*
  114-5   instead.  

  115     "is trivial and inline" ==> "is trivial"              

  118     "underestimated" ==> "overestimated"

  132     It's not true that default parameter values can only be in a
          declaration; they can also be in a definition.  In practice,
          however, they are always in the declaration, because they can't be
          in both places.

  134     "An object's dynamic type is the type of the object it currently
          refers to." ==> "An object's dynamic type is determined by the type
          of the object it currently refers to."

  149     The text says that by not declaring any constructors, Set acquires a
          copy constructor.  This is wrong.  By not declaring any COPY
          constructors, Set acquires a copy constructor.

  162     The statement implies that virtual bases cannot be used with SI.  I
          reworded things to eliminate this misimpression.  In practice, they
          rarely are.

  179     The 2nd bullet on page 179 should say "defined" instead of "declared".

  197     Add index entry for "conceptually const member functions" for page 76.

The following changes were made between the fifth and sixth printings. You need to worry about these changes only if you have a copy of one of the first five printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------

  xiii    Added email address for comments to me (, and also     
          added info on FTPing errata list (from in the
          file pub/Effective_C++_errata.txt).
 3, 14    ANSI ==> ANSI/ISO                                    
    15    Add reference to Steve Teale's IOStreams Handbook (Addison-Wesley,
    26    The ANSI/ISO committee has extended the language to include
          operators new[] and delete[] for managing array memory.  I added a
          footnote to this effect and cited the 5/93 C++ Report.
    31    After calling ::new, add this line:                  
            if (newBlock == 0) return 0;
    32    possibly as much as two or three times faster =>     
          possibly as much as an order of magnitude faster
    43    Add a copy constructor to both EnemyTarget and EnemyTank, and have
          this constructor also increment the count fields. 
    71    Extra right parenthesis in pseudo-code at top of page.
   138    The ANSI/ISO committee standardizing C++ has now added support for
          runtime type identification.  I added a footnote to this effect,
          cited the 7-8/93 issue of the C++ Report for a description, and
          offered an admonition that using RTTI is still almost always a bad
   147    It is not true that the calls to insert and remove would be
          infinitely recursive, because the number of parameters differ in
          the declaration and the call.  The explicit qualification is needed
          because the local names insert and remove shadow those in the
          private base class. 

   163    "It depends on A" => "It depends on how B and C inherit from A"
 163-5    All the functions returning char* should return const char* instead.
   180    In bullet 2, "declare a file static object" ==>     
          "define a file static object."
   181    In middle of page, both uses of "declared" should be "defined."
   191    not expected until at least 1993 => not expected until at least 1996

The following changes were made between the sixth and seventh printings. You need to worry about these changes only if you have a copy of one of the first six printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------

    15    There is a forward reference to a discussion of placement new in
          Item 8, but Item 8 contains no such discussion.  I eliminated the
          mention of placement new and the forward reference.
    21    The ANSI/ISO committee has respecified the behavior of operator
    25    new so that it now throws an exception of instead of returning 0.
          I added a footnote to this effect.
    50    The ANSI/ISO standardization committee has now fixed the lifetime
          of temporary objects to be until the end of the statement (more or
          less) in which they are created.  I added a footnote and a
          reference to an article in the 1/94 C++ Report.
    53    I reworded things to avoid implying that you can only use the
          explicit call form of base::operator= if the base class
          explicitly declares an operator=.  In fact, it should always
          be legal, but many compilers disallow it.
    78    I added a footnote indicating that there is no longer a need to cast
          away const for conceptual constness, and I cited the "mutable"
          article in the 1/94 C++ Report.

    93    The ANSI/ISO committee has now voted explicit support for namespaces
   203    into the standard; I cited the 11-12/93 C++ Report article.  Page
          203 now contains an index entry for "namespaces."
    97    It's not true that operator char*() returns a  pointer to data;  it
          returns a pointer to what data points to.  This is at the bottom of
          the page.  
   109    Compilers need not generate code for out-of-line inline functions
          that are not called, nor does the language require them to put one
          in each translation unit.  Instead of saying you WILL get multiple
          copies, say you MAY. 
   157    Reword to avoid implying that the example is verbatim out of the
          ARM.  It is only based on an ARM example.
   161    The memory layout picture for virtual bases is wrong;  the memory
          must be continuous.  Change the picture and update the text.  Also
          note that there must be two pointers to the A part, one from B and
          one from C. 
   163    Reword to indicate that RTTI removes the restriction  
   137    against downcasting.  Also update the index entry for 
   205    RTTI.

The following changes were made between the eigth and ninth printings. You need to worry about these changes only if you have a copy of one of the first eight printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------
  26, 50, Updated footnotes on new language features to refer to Bjarne
  78, 93, Stroustrup's "The Design and Evolution of C++,"
  138     Addison-Wesley, 1994.  This book is much easier to find than
          the back issues of the C++ Report I had been citing.

   xiii   Updated the location of the errata file.  It's now      
          available via anonymous FTP from in the directory
 and the file meyers.effectivec++.errata. 
    13    It's not true that an operator<< for ComplexInt        
          must exist -- the class might declare an implicit
          type conversion operator so that a call to operator<<
          succeeds.  I reworded this.
    35    I say the strings a and b are being declared, but      
          according to the terminology I define in the
          introduction, those are definitions, not declarations. 
    50    The type of a string literal is char[], not char*.
    78    The rules on const objects are now different.  A       
          const object becomes const at the end of its
          construction and remains const until its
          destructor is called.  The results of trying to
          change a const object through any means
          (including cast away const) are now undefined.  I reworded
          the paragraph that discusses this.
    88    Now that non-virtual member function templates         
          are legal, this NULL trick is legal after all.  I added a 
          footnote to this effect.  
   106    Added a footnote about the new feature (added 3/94)      
          that allows const class static ints to be initialized
          in the class definition.  
   135    I replaced the type long with double in makeDeposit,      
          makeWithdrawal, and balance.

   164    There is no reason to make RealPerson's functions      
          virtual, because, as a protected class,
          RealPerson will never be instantiated, and each
          inheriting class from RealPerson will use the
          "::" notation to call up to RealPerson, which
          will turn off virtual binding.  Hence all the
          functions in the class should be nonvirtual, and I made that
          change. This doesn't cause any problems, because
          RealPerson isn't supposed to have public derived
          classes, only private ones.
   171    In the first bullet, I changed the description so there's 
          no implication that abstract subclasses must provide
          an implementation.  Only concrete subclasses must do so.
   204-5  Removed index entries for "read-only memory, and this" and
          for "this, and read-only memory."  This goes along with the
          textual changes I made on page 78 (see above).

The following changes were made between the ninth and tenth printings. You need to worry about these changes only if you have a copy of one of the first nine printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------
    24    It is now legal to have member templates, but that still
          won't make it possible to write a template to create member
          functions for different classes.  I reworded the next-to-last
          paragraph in Item 7 to avoid implying otherwise.
   136    The declaration of List<T>::insert lacked a return type.  I
          made the return type void.
    98    The last line on the page should refer to a pointer-to-const,
          not to a constant pointer. 

The following changes were made between the tenth and eleventh printings. You need to worry about these changes only if you have a copy of one of the first ten printings of the book:

  PAGES                                MODIFICATION
  ------  ----------------------------------------------------------------------
    43    The EnemyTank copy constructor should use its member
          initialization list to ensure that the EnemyTarget copy constructor
          is invoked when an EnemyTank is copied. 
    33    C++ guarantees it's safe to delete the null pointer, so the
          top of operator delete should check deadObject against null
          and return immediately if the test succeeds.