| | Updated 2005.01.03This page contains the complete current list of all known errata and updates for the book Exceptional C++ Style (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. 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 CategoriesCategory | Description | Fmt | Format: Change to page layout or text formatting only. | Typ | Typo: Correction of simple typographical errors, cut-and-paste errors, and dyslexic mistakes. | Enh | Enhancement: Addition of new or clarifying material. | Cor | Correction: Change made to correct a substantive error that could mislead a reader; does not include typos and occasional dyslexia. |
Errata (in page number order)Page | Type | Reported | Fixed Printing | Description | 6 | Fmt | 2004.08.01 | 2 | In numbered paragraph 1, "correct" shouldn't be in code font. | 8 | Cor | 2004.08.22 Carl Daniel | 2 | In paragraph 5, change: The new buffer initially holds zeroes To: The new buffer initially holds undefined values (often zeroes) | 11 | Typ | 2004.08.22 Carl Daniel | 2 | In paragraph 1, the way it was written unintentionally implied that the C++ standard is based on C99 (the C++ standard is based on C95 = C90 + some later corrigenda + the 1995 amendment). Change: Throwing off the shackles and limitations of the C standard [C99], on which the C++ standard [C++03] is based, To: Throwing off the shackles and limitations of the C standard (currently [C99]; the C++ standard [C++03] is based on an earlier version of C), | 12 | Typ | 2004.11.02 Chris Breen | 2 | In each of the two code examples, change: PrettyFormat( value, buf ); To: PrettyFormat( value, smallBuf ); | 27-28 | Cor | 2004.11.30 Igor Krassikov and Alexander Krotov | 2 | Remove spurious parentheses that actually are not valid C++ syntax for taking a pointer to member. In the Question 2 code on page 27, and in two places on page 28, change: &(std::vector<int>::clear) To: &std::vector<int>::clear | 39 | Typ | 2004.09.07 Jason Shirk | 2 | In Example 6-2(b), there is a missing return type. Change: template<> swap<MyClass>( MyClass& a, MyClass& b ) { // throw() To: template<> void swap<MyClass>( MyClass& a, MyClass& b ) { // throw() | 39 | Typ | 2004.09.17 Bronek Kozicki | 2 | In Example 6-2(c), there is the same missing return type. Change: swap( MyClass& a, MyClass& b ) /* throw() */ { To: void swap( MyClass& a, MyClass& b ) /* throw() */ { | 41 | Typ | 2004.09.28 Igor Krassikov | 2 | In the first line of each of the first two paragraphs, change: copy assignment To: copy construction | 58 | Fmt | 2004.08.01 | 2 | In footnote 12, "boost" should be in variable-width code font. | 72 | Fmt | 2004.08.01 | 2 | In footnote 18, the final "export" should be in code font. | 102 | Fmt | 2004.09.14 Ramsay Jones | 2 | To make Example 14-2 and Figure 14-1 a little more consistent to avoid needless confusion, change the order of the base classes (this has no effect), change: class D2 : public B3, virtual public V2 { }; To: class D2 : virtual public V2, public B3 { }; | 131-2 | Typ | 2004.09.07 Jason Shirk | 2 | In Examples 18-1 and 18-2, there is missing whitespace between the "int" return type and the function name. In both examples, change: intProcess To: int Process And twice in Example 18-2, change: intDoProcess... To: int DoProcess... | 144 | Typ | 2004.09.14 Ramsay Jones | 2 | Some cut-and-paste typos. In paragraph 1, change: An implicitly declared default constructor To: An implicitly declared copy constructor In paragraph 4, change: An implicitly declared default constructor To: An implicitly declared copy assignment operator In paragraph 5, change: can throw anything that a base or member copy constructor could throw To: can throw anything that a base or member copy assignment operator could throw | 145 | Typ | 2004.09.17 Bronek Kozicki | 2 | In the second code block, there is a missing parameter name. Change: inline X& X::operator=( X& ) throw() { i_ = other.i_; return *this; } To: inline X& X::operator=( X& other ) throw() { i_ = other.i_; return *this; } | 164 166 168 169 | Cor | 2004.11.02 Josh Lehrer | 2 | Change FastMemory() temporary to a named variable. On pages 164 and 168, in the Question 3 code, change: Derived* p4 = new (FastMemory()) Derived; // 4 To: FastMemory f; Derived* p4 = new (f) Derived; // 4 On page 166, Example 22-1(b), change: new (FastMemory()) T; // calls some user-supplied To: FastMemory f new (f) T; // calls some user-supplied On page 169, in the code example, change: Derived* p4 = new (FastMemory()) Derived; // calls Base::operator new() To: FastMemory f; Derived* p4 = new (f) Derived; // calls Base::operator new() | 176 | Enh | 2004.08.20 Stephan Lavavej and Ryan Myers | 2 | In numbered paragraph 1, I've reworded some text for greater clarity. Change: 1. Checking new failure is useless on systems that don’t commit memory until the memory is used. On some operating systems, including but not limited to Linuxes,29 memory allocation always succeeds. Full stop. To: 1. Checking new failure can be useless on systems that don’t commit memory until the memory is used. On some operating systems,29 the operating system’s underlying memory allocation function always succeeds. Full stop. And in footnote 29, change: Lazy-commit is also a configurable feature on some other operating systems. To: Lazy-commit is a default or configurable feature on some versions of Linux, AIX, and other operating systems. Some more detail that doesn't fit in the book: Something you need to know about and turn off: Specifically, Linux kernels before 2.6 have this as their default and unconfigurable behavior, and apparently the kernel team suggested that gcc should rewrite their malloc to do exactly what I described in this Item as an unacceptable workaround -- namely that gcc should install a SIGSEGV signal handler and touch the pages themselves before returning a pointer. Of course, gcc would take the blame for the performance hit. Still, many people provided patches for glibc to do so, or personally wrapped malloc/new for their own apps, because even such a performance hit was preferable to unpredictable behavior and the possibility of crashing anytime you touch memory you think you own. If you are using a kernel older than 2.6, I strongly recommend you do this too. Then in 2.6 the kernel team relented and provided a flag to turn this off. As of this erratum entry writing, however, I do not know of any Linux distribution that does not have this unpredictable behavior on by default. If you are using a Linux kernel 2.6 or later (and especially if you're using Linux as a server), I urge you to run (don't walk) to find the flag for this behavior and turn it off. It's not a good idea to make unpredictable behavior the required behavior (pre-2.6), or even the default behavior (2.6 and later). | 191 | Typ | 2004.11.02 Josh Lehrer | 2 | In paragraph 4, for consistency, change: 3.14159 * 2.71828 * 3.14159 * 2.71828 To: (3.14159 * 2.71828) * (3.14159 * 2.71828) | 202 | Typ | 2004.11.26 Igor Krassikov | 2 | In paragraph 3, change: although it wastes two possible values To: although it wastes a possible value | 204-5 | Typ | 2004.09.14 Ramsay Jones | 2 | In the Question 1 code, "p" should be "dest" -- and while I'm at it I'll also change "dest" to "dst" just for consistency because I call that parameter "dst" later on (this has no effect on the code's correctness because the formal parameter name doesn't matter, but might as well be consistent). On page 204, in Question 1's code, change: // Get num bits starting with the start-th bit, // and store the result starting with the first // bit of p. // void Get( size_t start, size_t num, unsigned char* dest ) const; To: // Get num bits starting with the start-th bit, // and store the result starting with the first // bit of dst. // void Get( size_t start, size_t num, unsigned char* dst ) const; On page 205, where Question 1's code is quoted, change: void Get( size_t start, size_t num, unsigned char* dest ) const; To: void Get( size_t start, size_t num, unsigned char* dst ) const; | 233 | Typ | 2004.09.14 Ramsay Jones | 2 | In paragraph 6, change: that member's name To: that variable’s name | 250 | Typ | 2004.11.27 Igor Krassikov | 2 | In numbered paragraph 4, a 9 turned into a 6 in the cross-reference. Change: Item 36 in More Exceptional C++ [Sutter02] To: Item 39 in More Exceptional C++ [Sutter02] | 253 | Typ | 2004.11.30 Igor Krassikov | 2 | In numbered paragraph 14, the cross-reference got mistyped. Change: see [Sutter00, Item 39] To: see [Sutter00, Item 6] | 255-6 | Typ | 2004.11.30 Igor Krassikov | 2 | When reformatting the code for the book I didn't update all the line counts. On page 255, change: // Solution 2 uses a pair instead of reinventing a pair-like helper class. Now we’re // down to 13 lines, from the original 23. Of the 14 lines, 9 are purpose-specific, // and 5 are directly reusable in other contexts. To: // Solution 2 uses a pair instead of reinventing a pair-like helper class. Now we’re // down to 12 lines, from the original 23. Of the 12 lines, 8 are purpose-specific, // and 4 are directly reusable in other contexts. On page 256, change: // Here we still have 15 lines, but more are reusable. This version uses more space To: // Here we still have 13 lines, but more are reusable. This version uses more space | 259 | Typ | 2004.11.30 Igor Krassikov | 2 | In numbered paragraph 1, change: (For a complete example, see Item 11 of Exceptional C++ [Sutter00].) To: (For a complete example, see Item 11 and its context in Exceptional C++ [Sutter00].) | 263 | Cor | 2004.09.14 Ramsay Jones | 2 | In paragraph 3, something appeared as a template parameter that should have been a constructor parameter. Change: Now it’s possible to have, for example, a list< callback< Widget, &Widget::SomeFunc > > To: Now it’s possible to write, for example: list< callback< Widget > > lcw( w, &Widget::SomeFunc ); | 287 | Typ | 2004.09.14 Ramsay Jones | 2 | In the last paragraph, change: 1998 To: 2003 | 297 | Cor | 2004.09.27 Jim Leahy | 2 | In the first two code examples, change: != To: == | |