Tuesday, January 1, 2002

Updated Errata Lists

As part of my transition-to-a-new-year housecleaning, I've updated the
errata lists for all of my publications:

Effective C++ http://www.aristeia.com/BookErrata/ec++2e-errata.html
More Effective C++ http://www.aristeia.com/BookErrata/mec++-errata.html
Effective STL http://www.aristeia.com/BookErrata/estl1e-errata.html
Effective C++ CD http://www.aristeia.com/BookErrata/cd1e-errata.html

These lists are now comprehensive: all the bugs I know about are in those

In an ongoing effort to make this mailing list worth subscribing to, I've
listed all the new errata entries below. This mailing list is the only way
to see incremental changes to the errata lists.

Happy New Year!



-------- --- ----- ------------------------------------------------ --------
11/10/01 sdm xiii Change all URLs and email addresses that mention
xv awl.com to URLs/email addresses at aristeia.com
xvi because, despite over six years of trying, the
237 web morons at AW are incapable of maintaining
valid URLs and email addresses.

9/21/01 pxm 6-7 I should clarify that operator+ is assumed to be
a friend of String, hence has access to

7/ 6/01 ga Items Include exception specs for operator new. This
7-8 would make parts of these Items easier to
follow. On the other hand, if I use exception
specs here, I'd need to use them in Items 9-10,
too, and also on operator delete and possibly
elsewhere. The book currently uses almost no
exception specs, and perhaps it is more
consistent that way.

7/ 6/01 ga 51 Regarding the para after the first code
fragment, the place pointed to by a and c will
actually be deleted three times, because it will
already have been deleted when b went out of

7/ 6/01 ga 63-64 The word "twist" is repeated within a short
range. Reword.

7/ 6/01 ga 64 "freestanding functions" ==> "actual
functions in the object code"

7/ 6/01 ga 182 Another common synonym for layering is

10/17/01 js 202 In the first para, the phrase "begs the question"
is improperly used. Reword.

7/ 6/01 ga 203 In last sentence "PersonInfo::name" ==>

! 7/ 6/01 ga 226 In 2nd to last para, "string" isn't a template,
it's a typedef for a template. Reword.

Interesting Comments:

-------- --- ----- -----------------------------------------------------------
7/ 3/01 jcj Item 1 Regarding the argument that using a macro to represent a
floating point literal (such as on page 13) is more space-
efficient than using a const object, jcj writes:

The [const] form is at least as efficient as the #define
because when the preprocessor replaces ASPECT_RATIO with
1.653 in one's source code, that value must be stored
somewhere in the binary machine code. Clearly the fact
that one has a floating-point literal, in addition to the
fact that I can think of no machines that have any
instructions that take floating-point immediates, it is
quite obvious that 99.9% of the time 1.653 will occupy
some typically 64-bit space in memory that will be loaded
and used just like a constant would. In fact, when you
realize that the preprocessor and the compiler may not be
very tightly coupled, the #define form would define a
floating point literal at every point ASPECT_RATIO is
used, where the const form would only have one instance in
memory no matter how many uses there are. When you have
consts that refer to types that may be allowed as
immediates in the instruction set of the compiler, it is
possible that the #define could be faster if the compiler
did not optimize in the same way, but in general I'd be
more worried about 50 floating-point literals peppered
throughout my code than 1 constant used 50 times.

9/10/01 lz 98 If you are using a library with a const-incorrect function
prototype such as that for strlen on this page, there is a
solution better than using a cast at every point in the
program where you call the incorrectly-declared function:
write a wrapper function to perform the cast, then call the
wrapper. In the example on this page, the wrapper function
would look like this:
inline strlen(const char *s)
{ return strlen(const_cast(s); }



-------- --- ----- ------------------------------------------------ --------
11/10/01 sdm 8 Change all URLs and email addresses that mention
287 awlcom to URLs/email addresses at aristeia.com
because, despite over six years of trying, the
web morons at AW are incapable of maintaining
valid URLs and email addresses.

12/20/01 pd 11 Wording similar to the following is better for
the final paragraph on this page:

References, then, are the feature of choice
when you know you have something to refer to
and when you'll never want to refer to
anything else. They are also to be used when
implementing operators whose syntactic
requirements make the use of pointers
undesirable. In all other cases, stick with

10/ 1/01 jfn 56 In the last sentence before the code example at
the bottom of the page, "private static member
function" ==> "private member function". This
is what I hope is the final undo for the
incorrect "correction" I added on 10/4/99;
consult em's correction reported on 1/1/00 for

! 12/ 5/01 at 63 The first line of prose on this page is
incorrect; section 15.1/5 of the Standard makes
clear that implementations may optimize away the
creation of a separate exception object:

If the use of the temporary object can be
eliminated without changing the meaning of the
program except for the execution of
constructors and destructors associated with
the use of the temporary object (12.2), then
the exception in the handler can be
initialized directly with the argument of the
throw expression.

However, my remark that a catch block couldn't
modify localWidget continues to be true, as does
my observation that throwing an exception is
typically much slower than passing a parameter.

3/12/01 wds 120 Bad hyphenation in 2nd-to-last para: "runt-ime"
==> "run-time".

! 3/22/01 wcm 209 RCPtr and RCIPtr behave inconsistently with
210 respect to automatically performing COW on
pointee objects. The fundamental problem is that
my fix for we's bug report of 3/4/96 above was
incorrect, and I should have realized that when I
had to "bend" the notion of constness to
implement it. As Andrei Alexandrescu noted in
his Modern C++ Design,

Smart pointer are not the best place to
implement COW, because smart pointers cannot
differentiate between calls to const and
non-const member functions of the pointee
object. (Page 165)

The responsibility for triggering COW thus rests
on smart pointer clients, and this is precisely
what I do in the non-const String::operator[] on
page 207 (note the creation of a new StringValue
object). In responding to we's bug report, I
shouldn't have modified RCIPtr. Instead, I
should have modified RCWidget::doThis to call
value->makeCopy before calling value->doThis.
That's what I'll do now, and I'll update the Item
29 source code, too.

9/22/01 sdm 222 Bad justification of last line on page.

! 10/10/01 pb 272 Notes pb, "'extern "C"' doesn't mean that name
mangling is suppressed. Rather, it means that names
should be mangled in the way that the targetted C
compiler mangles them. Some C compilers put an
underscore at the front of a name; others put an
underscore at the end; some don't change the name at
all. A name declared as 'extern "C"' should be
mangled in the same way."

Interesting Comments:

-------- --- ----- -----------------------------------------------------------
11/24/01 iw Item 7 As it turns out, it is possible to overload the ||
and &&
operators while still preserving their short-circuit
semantics, and this is not uncommon in libraries based on
template metaprogramming. Because my objection to
overloading these operators is based on the loss of
short-circuit semantics, I don't oppose libraries that
overload them as long as they also preserve their
short-circuitedness. For an example of a library that
overloads them for good reason, check out the href="http://www.oonumerics.org/tmpw01/jarvi.pdf">Lambda Library
described at the href="http://www.oonumerics.org/tmpw01/schedule.html">Proceedings of the 2001
Workshop on C++
Template Programming
. (iw wasn't the only person to
send me the essence of this comment, but his email was the
one that inspired me to add it to the errata list.)

9/23/01 lz Item 21 One drawback to lots of overloading is that it can lead to
ambiguities. For example, if you declare both f(int) and
f(long) and a client calls f with a char or a double, the
call will be ambiguous until the client casts the char or
double to an int or long.



-------- --- ----- ------------------------------------------------ --------
9/26/01 kh 13 The definition of contiguous-memory containers
should say that such containers are assumed to
store more than one element per dynamically
allocated chunk of memory; they are not
required to do so. In theory, both deque and
string could be implemented as arrays of pointers
to objects, for example, though no sane imple-
mentation would do things that way. (Very large
objects may be stored only one element per chunk
of memory in a deque, though one would have to
wonder why such large objects were being stored
in an STL container in the first place.)

! 11/ 5/01 sdm 61 In 2nd-to-last para, the claim that C++
guarantees that local objects are destroyed if
an exception is thrown is not quite true. The
guarantee holds only if the exception is caught.

9/27/01 lz 77 In the second section of example code, the call
to vd.resize(...) is missing the final closing

! 11/ 5/01 ma 134 In last code example, "widgets.begin()+20" should
be "widgets.begin()+19".

11/ 5/01 sdm 111 In 2nd-to-last line of Item 24, "map" should be
in code font.

11/18/01 sk 160 PointAverage's constructor should list its member
initializers in the order in which the data
members are defined in the class. (Shame on me
for making this mistake, as it is the topic of
Item 13 in my href="http://www.awl.com/cseng/titles/0-201-92488-9/">Effective

12/26/01 jdl 211 In 2nd para, "I uses" ==> "I use".

! 10/ 4/01 rd 207 The comment above the initialization of rangeBegin
is incorrect. It should read as follows:
Initialize rangeBegin to point to the element
following the last occurrence of a value greater
than or equal to y. If there is no such value,
initialize rangeBegin to v.begin(). If the last
occurrence of the value is the last element in v,
initialize rangeBegin to v.end().

11/10/01 sdm 225 Change all URLs and email addresses that mention
228 awl.com to URLs/email addresses at aristeia.com
because, despite over six years of trying, the
web morons at AW are incapable of maintaining
valid URLs and email addresses.

Interesting Comments:

-------- --- ----- -----------------------------------------------------------
9/24/01 mm Item 1 Sometimes, the best data structure for a problem is not in
the STL at all. mm writes that "One of the biggest misuses
that I've seen of the STL is when maps are used instead of
sparse matrix data structures. ... In many applications, a
matrix is very sparse. It is often the case that there is
just 2 to 5 entries per column, even in matrices with tens
of thousands of rows. ... There are highly efficient data
structures for doing this, and they're not very
complicated. ... There are lots of efficient algorithms
available for doing all sorts of operations on a matrix,
and there are various places on the internet (especially
www.netlib.org) that
have classes that encapsulate this."

12/22/01 sdm 37-39 Windows programmers experimenting with my
DeleteObject class should beware that there is a
Windows function with the same name. (I didn't know
what when I wrote the book.)

11/14/01 axg Item 10 One way to avoid creating allocators with per-object state
is to declare all member functions static.

11/ 5/01 sdm 60-61 An alternative to creating and using the Lock template is
to use href="http://www.cuj.com/experts/1812/alexandr.htm">Alexandrescu's and
Marginean's ScopeGuard

11/13/01 ib 60-62 Given that manual concurrency control is a necessity, you
might consider using href="http://www.boost.org/libs/thread/doc/index.html">the cross-platform
threading library
available at Boost

11/12/01 sdm Item 25 Regarding the choice of basing hashed containers on
equality or equivalence, P. J. Plauger, founder of
Dinkumware, posted this to comp.lang.c++.moderated on

Our latest version of the hash template classes aims for
the best of both worlds. Turns out it can hash properly
given either a strict weak ordering, as in operator
less<T>, or an inequality comparison, as in
not_equal<T>. So we add a partial specialization
looks for SGI-style template parameters and invert the
sense of the supplied predicate. The upshot is that you
can use our hash tables as a drop-in replacement for
map/set, using a strict weak ordering, or as a drop-in
replacement for SGI-style hash_map/set, using an
(in)equality comparison.

If you're interested in the choice between equality and
equivalence for hashed containers, you might want to
the thread from which this posting is taken

11/14/01 yd 243-244 yd writes: "I took your advice and turned on the
configuration. However I was not able to compile, due to a
Microsoft bug (Q241949 in the MS knowledge base). MSVC6
supports member templates, but only when they are defined
inside the class body. The SGI STL has many such members
defined out-of-body. Getting it to compile would require
extensive cut-and-paste throughout. I haven't checked
STLport, but chances are it has the same problem since
it's derived from SGI STL."
I know from personal experience that some constructs
requiring member templates work with MSVC6 and STLport, so
this suggests that STLport has modified the SGI
distribution on which it is based to better work with
MSVC6. That suggests that STLport's STL may be a better
choice than SGI's, at least as regards support for member
function templates under MSVC6.



-------- --- ------------------------------------------------------- --------
9/18/01 dp The CD doesn't work properly with IE6, e.g., image and
chunk size choices don't appear in the navigation area,
and lines don't break to fit the browser window.
| Check out the *new* "THE C++ Seminar" |
| http://www.gotw.ca/cpp_seminar/ |

No comments: