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.

