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 ec++@aristeia.com 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 174 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 constructors" 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 [] temp.data;" after declaring temp and before assigning to temp.data. 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 (johnw@aw.com), and also added info on FTPing errata list (from wilma.cs.brown.edu in the file pub/Effective_C++_errata.txt). 3, 14 ANSI ==> ANSI/ISO 163 191 15 Add reference to Steve Teale's IOStreams Handbook (Addison-Wesley, 1993). 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 idea. 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 aw.com in the directory aw.prof.comp.series 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.