C++ Coding Standards - Errata List

Home Blog Talks Books & Articles Training & Consulting

Up
Next

On the
blog
RSS feed March 25: We Have FDIS! (Trip Report: March 2011 C++ Standards Meeting)
March 24:
Book on PPL Is Now Available
January 14: Interview on Channel 9
December 31: 2010: Cyberpunk World

Updated 2005.09.05

This page contains the complete current list of all known errata and updates for the book C++ Coding Standards (English edition).

If you think you've found a new erratum not already on this list, please submit new errata here

This errata list is maintained by the author (Sutter).

The individual errata entries are listed in page number order. For each one, I have included the page number as of the last printing not incorporating the suggestion (including "xref" cross-references to related entries for other pages), the severity (summarized below), the person who first reported the erratum and when, the earliest English printing incorporating the correction, and a description of the erratum and its correction.

Errata Categories

CategoryDescription
FmtFormat: Change to page layout or text formatting only.
RefReference: Addition of new references to other books and articles.
TypTypo: Correction of simple typographical errors, cut-and-paste errors, and dyslexic mistakes.
EnhEnhancement: Addition of new or clarifying material.
CorCorrection: Change made to correct a substantive error that could mislead a reader, particularly in code examples; does not include typos and occasional dyslexia.

Errata (in page number order)

PageTypeReportedFixed
Printing
Description

xvii

Cor

2004.10.10

2

Added some missing reviewers to the acknowledgments: Travis Brown, Neal Coombes, Attila Feher, Bartosz Milewski, and Balog Pal.

15

Typ

2004.12.14
Stephen Blake

3

In the first bullet, change:
Use flexible, dynamically-allocated data and instead of fixed-size arrays:

To:
Use flexible, dynamically-allocated data instead of fixed-size arrays:

15

Enh

2005.01.28
Manuel Menezes de Sequeira

3

In the final paragraph, change:
Avoid polynomial algorithms where reasonable.

To:
Avoid worse-than-linear polynomial algorithms where reasonable.

25

Cor

2004.11.14
Frank Starrost

2

Change the second code example from:
shared_ptr sp1(new Widget), sp2(new Widget);
Fun( sp1, sp2 );

To:
shared_ptr<Widget> sp1(new Widget), sp2(new Widget);
Fun( sp1, sp2 );

33

Ref

2004.11.25
Scott Meyers

2

Added reference to [Meyers96] §1.

35
(and 197)

Typ

2004.11.14
Frank Starrost

2

In the Summary for Item 18, remove the spurious closing parenthesis. Change:
so too with variables):

To:
so too with variables:

51

Typ

2005.01.29
Manuel Menezes de Sequeira

3

In paragraph 4, change:
s == String(“Hello”)

To:
someString == String(“Hello”)

53

Cor

2004.12.05
Hyman Rosen

3

In paragraph 3, change:
For example, if the following code invokes a user-defined comma operator, it is unspecified which of f or g receives the value 0 and which receives the value 1.
  int i = 0;
  f( i++ ), g( i++ ); // see also Item 31

To:
For example, if the following code invokes a user-defined comma operator, it is unspecified whether g receives the value 0 or the value 1.
  int i = 0;
  f( i++ ), g( i ); // see also Item 31

53

Cor

2004.12.05
Hyman Rosen

3

In the last code line, change:
string s = getstr(), getstr();

To:
string s; s = getstr(), getstr();

56

Enh

2004.11.29
Attila Feher

2

For clarity, in bulleted paragraph 7 change:
Is usually instantiated dynamically on the heap and used via a (smart) pointer.

To:
Is usually instantiated dynamically on the heap as part of a concrete derived class object, and used via a (smart) pointer.

60

Typ

2005.01.29
Manuel Menezes de Sequeira

3

In paragraph 2, change:
and54

To:
and 54

60-61

Enh

2004.11.29
Attila Feher

2

Added another example on page 61, which after page rebalancing also moved two lines from the top of page 61 to the bottom of page 60. On page 61 change:
Example:

To:
Example 1:

And then just before the References subhead add a new example:
Example 2: std::unary_function. Although std::unary_function has no virtual functions, it is indeed designed to be a base class, and is not outlawed by this Item. (But unary_function could be improved by giving it a protected destructor; see Item 50.)

76

Typ

2004.12.21
Marcelo Pinto

3

In paragraph 5, change:
There are at least three reasons you might Pimpl,

To:
There are at least three reasons you might use Pimpl,

77

Typ

2004.11.15
Peter Niday

2

Three lines from the bottom of the page, change:
not all of the issues resolves by Pimpl

To:
not all of the issues resolved by Pimpl

87

Typ

2004.11.29
Michael Borghardt

2

In the second code example, change the single line from:
A() : s1_(), s2_() { s1 = “Hello, “; s2 = “world”; }

To:
A() : s1_(), s2_() { s1_ = “Hello, “; s2_ = “world”; }

96

Typ

2004.11.21
Peter Niday

2

In paragraph 3, change:
The programmer’s intent to manipulate

To:
The programmer’s intent is to manipulate

98

Enh

2004.12.17
Robert Goddard

3

For clarity and to avoid confusion with other Items, change:
  virtual B* DoClone() const = 0;

To:
private:
  virtual B* DoClone() const = 0;

101Enh2005.09.04
SGuy
---

Just before the second code example, change:
Additionally, consider specializing std::swap for your own non-template types:

To:
Additionally, consider specializing std::swap for your own non-template types (but see Items 65 and 66):

110

Typ

2004.10.21

2

In paragraph 3, change:
tries to fall A::f(int)

To:
tries to call A::f(int)

112

Typ

2004.11.16
Brent Thale

2

Just before the last code example on the page, change:
do not definite

To:
do not define

116

Typ

2004.12.27
Marcelo Pinto

3

In paragraph 4, change:
a string that containers

To:
a string that contains

123

Typ

2004.10.21
Peter Niday

2

Fix cut-and-paste typo. In bullet 2, change:
that can be called with given arguments (here, none).

To:
that can be called with given arguments.

123

Cor

2004.12.05
Hyman Rosen

3

Spurious use of typename. In the Option 3 example, change:
typename S3Traits<T>::foo( t );

To:
S3Traits<T>::foo( t );

124

Typ

2004.12.04
Martin Sweitzer

3

Fix cut-and-paste typo. In the code at the bottom of the page, change:
// disables ADL: foo is not a point of customization

To:
// disables ADL: bar is not a point of customization

124Enh2005.09.04
SGuy
---

At the end of the paragraph that starts with "Prefer Option 3," add:
(But see Item 66.)

126
(and 202)
Enh2005.09.04
SGuy
---

In the end of the Summary paragraph for Item 66, change:
(See Item 57.)

To:
(See Items 56 and 57.)

Also, at the end of the Summary paragraph for Item 66, add:
(See Item 65 for alternatives.)

135

Enh

2004.12.27
Marcelo Pinto

3

In paragraph 4, change:
(which is also safer, because it works at a higher level of abstraction)

To:
(which is also safer, because it works at a higher level of abstraction; see Item 63)

141

Typ

2004.12.14
Gavin Greig

3

In the final paragraph, change:
First, note that you should turn always on exception handling

To:
First, note that you should always turn on exception handling

146
(and 204)

Typ

2004.11.29
Attila Feher

2

At the end of the Summary for Item 75, change:
Exceptions.)

To:
Exceptions).

151

Typ & Enh

2005.01.20
Weston Markham

3

For clarity and to fix a typo, in the first nonbulleted paragraph, change:

In paragraph 4, change:
because of your answers to the first three question in this Item

To:
because of your answers to the first three bulleted questions in this Item

155
(and 205)

Typ

2004.11.29
Attila Feher

2

In the Summary for Item 80, change:
to add an element to sequence

To:
to add an element to a sequence

157

Cor

2005.01.03
Jaroslav Kroupa

3

In the third code example, change:
c.erase( remove( c.begin(), c.end() ,value ) );

To:
c.erase( remove( c.begin(), c.end(), value ), c.end() );

163

Enh

2005.01.14
Manuel Menezes de Sequeira

3

In Example 1, the second code snippet assumes data is an array (and is a little lazy at that). That's because it came from material where data was indeed defined as an array. Since that's not necessary here, I'll go back to assuming it's a normal container, and vector in particular.

In paragraph 4, change:
transform( data, data + max, // copy elements from data

To:
transform( data.begin(), data.end(), // copy elements from data

163

Enh

2005.01.14
Manuel Menezes de Sequeira

3

In Example 2, the first code snippet could be changed to make the result usable outside the loop.

Change:
for( vector<int>::iterator i = v.begin(); i != v.end(); ++i )
  if( *i > x && *i < y ) break;

To:
vector<int>::iterator i = v.begin();
for( ; i != v.end(); ++i )
  if( *i > x && *i < y ) break;

164

Typ

2004.12.17
Robert Goddard

3

The printer seems to have truncated a line in the first code block on the page. It should read:
vector<int>::iterator i = find_if( v.begin(), v.end(),
                                   compose2( logical_and<bool>(),
                                             bind2nd(greater<int>(), x),
                                             bind2nd(less<int>(), y) ) );

165

Typ

2005.01.03
Manish Pagey

3

In the final paragraph, change:
there’s no motivation to replace a call the member count

To:
there’s no motivation to replace a call to the member count

167

Typ

2004.12.15
Chih-Chung Chang

3

In the second bullet paragraph, at the end, change:
whose weight is 10kg or less.

To:
whose weight is 10kg or more.

170

Cor

2004.12.17
Robert Goddard

2005.01.29
Manuel Menezes de Sequeira

3

In the middle of the page, change:
The workaround is to insert ptr_fun (or, for a member function, mem_fun or mem_fun_ref):
  inline bool IsHeavy( const Thing& ) { /*…*/ }
  find_if( v.begin(), v.end(), not1( ptr_fun<Thing,bool>( IsHeavy ) ) ); // ok: now it’s adaptable

Aside: Yes, it’s a pain that here you need to explicitly specify ptr_fun’s template arguments. This is another drawback to using functions. Briefly, the reason the template arguments are needed is that ptr_fun deduces the argument and return types exactly and creates a pointer_to_unary_function, which in turn helpfully tries to add another &, and references to references are not currently allowed by ISO C++. There are ways in which ptr_fun could, and probably should, be fixed so as to strip top-level const and & from non-pointer parameter and return types (see Item 89), but it doesn’t do that today.

To:
The usual workaround is to insert ptr_fun (or, for a member function, mem_fun or mem_fun_ref), which unfortunately doesn’t work in this particular case:
  inline bool IsHeavy( const Thing& ) { /*…*/ }
  find_if( v.begin(), v.end(), not1( ptr_fun( IsHeavy ) ) ); // a valiant attempt

It’s a pain that this wouldn’t work even if you explicitly specified ptr_fun’s template arguments. Briefly, the problem is that ptr_fun deduces the argument and return types exactly (in particular, the parameter type is deduced as const Thing&) and goes on to create internal machinery which, along the way, in turn helpfully tries to add another &, and references to references are not currently allowed by ISO C++. There are ways in which the standard language and/or library could, and probably should, be fixed so as to make this work correctly (e.g., by allowing references to references to collapse to a single reference; or see also Item 89), but it doesn’t do that today.

171

Enh

2005.01.29
Manuel Menezes de Sequeira

3

To avoid confusion, in paragraph 1, change:
This is because it’s illegal to instantiate a template type parameter with a function type directly:

To:
This is because it’s illegal to instantiate a template type parameter with a function directly:

178

Cor

2005.01.31
Manuel Menezes de Sequeira

3

The second checked_cast template, which is meant to work on reference casts, is incorrect because the operator== is applied to the objects (not their addresses) and because dynamic_cast throws an exception in the interesting cases (and the point is that we want an assertion, not an exception).

In the second checked_cast template, change:
assert( dynamic_cast<To>(from) == static_cast<To>(from) && ”checked_cast failed” );

To:
typedef tr1::remove_reference<To>::type* ToPtr;    // leverage [C++TR104]
assert( dynamic_cast<ToPtr>(&from) == static_cast<ToPtr>(&from) && ”checked_cast failed” );

179

Cor

2004.12.17
Robert Goddard

3

In the final code line, change:
return const_cast<Object&>( foo(ref) ); // have to const_cast the return type

To:
return const_cast<Object&>( f(ref) ); // have to const_cast the return type

180

Cor

2004.12.15
Konrad Hager

3

At the end of the Summary, change:
Derived* pd = (Base*)pb; // bad: C-style cast

To:
Derived* pd = (Derived*)pb; // bad: C-style cast

186

Ref

2004.11.25
Scott Meyers

2

Added reference to [Meyers96] §3.

 

Copyright © 2011 Herb Sutter