jsg, 5/30/06
[also in first printing]
Gotcha #62, p. 173
The implementation of overloaded
operator new has a potential integer overflow in the for loop "for( int
i = 0; i < n; ++i )" because i is a signed int and n is a size_t One
solution is to redeclare i as a size_t.
scd, 11/8/02
[also in first printing]
Gotcha #69, p. 203-204
The statement on page 204 that the order in which
the static message type objects are initialized is immaterial is
correct.
However, the Firewall Monostate on page 203 implements its
container
of message type pointers as a static data member, and this must be
initialized
before insertion of any pointers to static message type objects.
One correct implementation is to use a "lazy initialization" of the
container
just prior to the first insertion of a message type pointer. This
is the implementation used in the downloadable code.
fv, 2/21/03
[also in first printing]
Gotcha #87, p. 265, 266
On page 266, the expression ++++j is
"legal," but its behavior is undefined because the value of j is
accessed and set more than once without an intervening sequence
point.
On page 266, the expressions ++a = 10 and ++++a
suffer
from the same problem. While the text of the gotcha is still
"correct"
in a strict legal sense, the undefined nature of the expressions should
have been pointed out.
sb, 6/17/03
Gotcha #53, p. 145-146
Inexplicably, the argument to the base class
assignment operator is *this rather than rhs.
As
a result the assignment would (presumably) change only the derived
class
portion of the object.
The correct implementation of the assignment
on page 145 is
D &D::operator =( const D &rhs )
{
if( this != &rhs )
{
B::operator =(rhs);
C::operator =(rhs);
// assign any D-specific members...
}
return *this;
}
The correct implementation of the assignment
on page 146 is
D &D::operator =( const D &rhs )
{
if( this != &rhs )
{
A::operator =(rhs);
B::nonvirtassign(rhs);
C::nonvirtassign(rhs);
// assign any D-specific members...
}
return *this;
}
kh, 3/8/03
Gotcha #54, p. 149-150
The implementations of D's copy
operations
are not exception-safe. They should have ensured that the new X
object
was successfully allocated and initialized before the old X
object
was deleted.
rp, 11/6/05
Gotcha #67, p. 194
The DBLock class should have prevented copying by declating its
copy operations to be private and undefined. As it stands, copies
of a DBLock
object may cause multiple calls to unlockDB without an intervening call to lockDB.
scd, 11/8/02
Gotcha #69, p. 203-204
The statement on page 204 that the order in which
the static message type objects are initialized is immaterial is
correct.
However, the Firewall Monostate on page 203 implements its
container
of message type pointers as a static data member, and this must be
initialized
before insertion of any pointers to static message type objects.
One correct implementation is to use a "lazy initialization" of the
container
just prior to the first insertion of a message type pointer. This
is the implementation used in the downloadable code.
fv, 2/21/03
Gotcha #87, p. 265, 266
On page 266, the expression ++++j is
"legal," but its behavior is undefined because the value of j is
accessed and set more than once without an intervening sequence
point.
On page 266, the expressions ++a = 10 and ++++a
suffer
from the same problem. While the text of the gotcha is still
"correct"
in a strict legal sense, the undefined nature of the expressions should
have been pointed out.
bww, 2/23/03
Gotcha #88, p. 270
The rendition of the equivalent of the
compiler-generated
copy assignment operator for the Money class should be
implemented
as it is below, not as it is on page 270.
template <Currency currency>
Money<currency> &
Money<currency>::operator =( const
Money
&rhs ) {
myCurve_ = rhs.myCurve_;
// leak, alias and change of curve!
amt_ = rhs.amt_;
}
scd, 12/2/02
Gotcha #29, p. 77
The comment on the declaration of badButton
wraps around.
bb, 10/20/03
Gotcha #32, p. 83
The second and third bullet items in the quote
from the standard should not start with "The."
kh, 3/8/03
Gotcha #32, p. 85
The second argument to the get_token function
should be declared to be const char *, not char *.
That usage is (still) legal but deprecated.
kh, 3/8/03
Gotcha #42, p. 109
The operator () member of IsEven
should be declared to be a const member function.
ms, 2/19/03
Gotcha #44, p. 112
In the first sentence of this page, the reference
should be to Gotcha #5, not Gotcha #7.
kh, 3/8/03
Gotcha #60, p. 167
The use of the term "scalar" is incorrect
here.
Section 3.9/10 of the standard defines "scalar" as referring to
artihmetic,
enum, and pointer types only. This discussion of new and delete
should
have used the terms "arrays and non-arrays" rather than "arrays and
scalars"
so as to include class objects in the latter category.
kh, 3/8/03
Gotcha #62, p. 173
Since std::string::c_str never returns
a null pointer, it is not necessary for this implementation of an
overloaded
operator
new to check that the return value is non-null.
epn, 2/16/03
Gotcha #64, p. 178
"The principle reason..." should be "The
principal
reason..." Shameful! Perhaps I meant "The principled reason..."?
ct, 6/23/03
Gotcha #79, p. 239
"As Figure 7-16 shows, the identifier B::f
dominates..."
should read "As Figure 7-16 shows, the identifier B1::f
dominates..."