Errata for 3rd printing of The C++ Programming Language

Errata for Bjarne Stroustrup: The C++ Programming Language (3rd edition), Addison-Wesley, 1997. ISBN0-201-88954-4. Errata for the 3rd printing yielding the 4th.

Errors and Clarifications


Chapter 1:

pg 5 s/an insertion sort/a Shell sort/

Chapter 2:

pg 22 s/Fortran/Fortran77/

pg 30 s/push(stack/void push(stack/

pg 32 s/complex operator==/bool operator==/

pg 32 s/complex operator!=/bool operator!=/

pg 36 s/p.pop()/s_ref.pop()/

Chapter 3:

pg 65 s/template<class C, class T>/template<class C>/

Chapter 4:

pg 72 s/cin/std::cin/

pg 72 s/cout/std::cout/

pg 72 s/(secC.1)/(secC.1, C.3.4)/

Chapter 5:

pg 89 s/v2(10)/v2(i)/

pg 93 s/iostream.h/iostream/

pg 93 s/cout/std::cout/

pg 99 s/vec<Pair>/vector<Pair>/

pg 100 s/for (vector<Pair>::const_iterator p = pairs.begin(), p!=pairs.end(), ++p)/for (vector<Pair>::const_iterator p = pairs.begin(); p!=pairs.end(); ++p)/

Chapter 6:

pg 108 s/term+expression/expression+term/ same for -

pg 108 s/primary*term/term*primary/ same for /

pg 117 s/expr()/expr(false)/ twice

pg 118 add /if (input!=&cin) delete input;/ before the return

pg 121 s/(a=b<c)?(d=e):(f=g)/a=((b<c)?(d=e):(f=g))/

pg 133 s/String/string/ twice

pg 133 s/integer or pointer expression/arithmetic or pointer expression/

pg 134 s/only if p is./only if p is nonzero./

pg 135 s/The scope of d extends to/The scope of d extends from its point of declaration to/

pg 141 s/ccstring/cstring/

Chapter 7:

pg 148 Replace the first paragraph with

A value must be returned from a function that is not declared void
(however, main() is special; see sec3.2). Conversely, a value cannot
be returned from a void function. For example:
	int f1() { }			// error: no value returned
	void f2() { }			// ok

	int f3() { return 1; }	// ok
	void f4() { return 1; }	// error: return value in void function

	int f5() { return; }		// error: return value missing
	void f6() { return; }	// ok

pg 148 Add at the end: "A void function cannot return a value.However, a call of a void function doesn't yield a value, so a voidfunction can use a call of a void function as the expression in a return statement. For example:

	void g(int* p);

	void h(int* p) { /* ... */ return g(p); }	// ok: return of ``no value''
This form of return is important when writing template functions where the return type is a template parameter (see sec" (recent standards change)

pg 159 s/:0/:\n"/ twice

Chapter 8:

pg 191 s/(cin)/(*input)/

pg 191 Add /if (input!=&cin) delete input;/ before the return

pg 192 s/It is an obvious candidate/It, input, and no_of_errors are obvious candidates/

pg 192 s/using std::cin;// s/(cin)/(*input)/

pg 193 s/(cin)/(*Driver::input)/ add statement deleting input and a return statement

Chapter 9:

pg 201 s/<algo>/<algorithm>/

pg 202 s/include guard (sec9.3.3)/for C++ compilers only (sec9.2.4)/

pg 209 s/ Token_value Lexer::curr_tok;/ Lexer::Token_value Lexer::curr_tok;/

pg 219 s/by returning 0./by returning a nonzero value./

pg 219 s/The order of invocation .../The destructor of an object created before a call of atexit(f) will be invoked after f is invoked. The destructor of an object created after a call of atexit(f) will be invoked before f is invoked./

Chapter 10:

pg 227 s/ s/today.month/today.m/ s/today.year/today.y/

pg 229 in set_default swap m and d twice

pg 243 s/otherwise, the compiler will try to generate one if needed./ otherwise, the compiler will try to generate one if needed and if the user hasn't declared other constructors./

pg 245 s/Here, the Table constructor is/Here, the Table default constructor is/

pg 255 s/<7/<8/

pg 259 s/main()/int main()/

Chapter 11:

pg 275 s/-6/-4/

pg 276 s/X::operator(Z)/X::operator=(Z)/

pg 283 s/Matrix& operator+(const Matrix&, const Matrix&)/Matrix& operator+(const Matrix& arg1, const Matrix& arg2)/

Chapter 12:

pg 309 s/print()/print_employee()/

Chapter 13:

pg 333 s/cout <<t/cout <<p->val/

Chapter 14:

pg 373 s/Vector::Range/Vector::Size/

pg 379 s/PFV/unexpected_handler/ five times

pg 380 s/set_new_handler/set_unexpected/

pg 380 s/PFV/terminate_handler/ thrice

pg 382 s/an implementation knows that the standard C library doesn't throw exceptions,/an implementation knows that only a few standard C library functions (such as atexit() and sort()) can throw exceptions,/

pg 385 s/ios_base::clear/ios_base::clear()/

Chapter 15:

pg 401 s/BB_slider/BBslider/

pg 409 s/BB_slider/BBslider/ four times

pg 411 s/p points to/r references/ (in comment)

pg 423 s/s*sizeof(Employee)/s*sizeof(Employee)+delta/

Chapter 16:

pg 443 add members:

	typedef typename A::pointer pointer;			// pointer to element
	typedef typename A::const_pointer const_pointer;

pg 447 s/T2/T/ thrice

pg 450 replace the last paragraph of sec16.3.4 with "A constructor given two arguments of the same type can lead to an apparent ambiguity. For example:

	vector<int> v(10,50);	// vector(size,value) or vector(iterator1,iterator2) ?
However, an int isn't an iterator and the implementation must ensure that this actually invokes
	vector(vector<int>::size_type, const int&, const vector<int>::allocator_type&);
rather than
	vector(vector<int>::iterator, vector<int>::iterator, const vector<int>::allocator_type&);
The library achieves this by suitable overloading of the constructors and handles the equivalent ambiguities for assign() and insert() (sec16.3.6) similarly." (recent standards resolution)

Chapter 17:

pg 478 s/operator<(const Message& x) {/operator<(const Message& x) const {/

pg 479 s/q.front()/

pg 479 s/and then retrieving them using pq.pop()./and then retrieving them using and pq.pop()./

pg 485 s/class value_compare : public binary_function<T,T,bool> {/ class value_compare : public binary_function<value_type,value_type,bool> {/

pg 490 the function print_numbers() should look like this:

	void print_numbers(const multimap<string,int>& phone_book)
		typedef multimap<string,int>::const_iterator I;
		pair<I,I> b = phone_book.equal_range("Stroustrup");
		for (I i = b.first; i != b.second; ++i) cout <second <<'\n';

pg 493 s/A basic_string (Chapter 20) argument does the same, except .../A basic_string (Chapter 20) argument does the same, except that the character '0' gives the bitvalue 0, the character '1' gives the bitvalue 1, and other characters cause an invalid_argument exception to be thrown.

pg 493 s/(non-'0' characters map to 1)/invalid_argument thrown/

pg 500 s/sec17.4.1.4/sec17.4.1.7/

pg 500 s/hash_map::// within the declaration of hash_map

pg 501 s/&v.last()/&v.back()/

Chapter 18:

pg 513 s/c./ls./ twice in f()

pg 513 s/iseq(c)/iseq(ls)/ in f()

pg 524 s/ Extract_officers(list<Person*> x)/Extract_officers(list<Person*>& x)/

pg530 s/copy_backward(vc.begin(),vc.end(),v.begin());/copy_backward(vc.begin(),vc.end(),v.end());/

pg 536 s/Iter/In/ thrice

pg 536 s/operator()(const Club& c) {/operator()(const Club& c) const {/

pg 536 s/havn"));/havn")));/

pg 539 s/operator()(const Book& b1, const Book& b2)/operator()(const Book& b1, const Book& b2) const/

Chapter 19:

pg 556 s/vi.size()/vi+vi.size()/

pg 558 replace

	ostream_iterator(ostream_type& s, const Ch* delimiter);
	ostream_iterator(ostream_type& s, const Ch* delim);	// write delim after each output value!

pg 563 s/Iter pp =p;/Iter pp = c->begin();/

pg 565 terminate begin() and end() with a } each

pg 565 s/Checked_iter<C> operator[]/typename C::reference_type operator[]/

pg 569 replace the definition of reserve by

	void reserve(size_type n)
		if (n<=capacity()) return;

		iterator p = alloc.allocate(n);
		iterator q = v;

		while (q<v+size()) {				// copy existing elements
		alloc.deallocate(v,capacity());		// free old space
		v = p;
		// ...	

pg 570 s/csize/size/

pg 576 s/delete[](void,/delete[](void*,/

Chapter 20:

pg 582 s/list-like/complete set of/

pg 582 s/(sec16.3.6)//

pg 583 s/find_first/find/ thrice

pg 585 s/Ch operator[]/const_reference operator[]/

pg 586 s/error: no string(const char*,int,int)/string(string(p),7,3), possibly expensive/

pg 586 s/fom p/from s/

pg 591 s/return s2.size()-s.size();/ return (s2.size()==s.size()) ? 0 : (s.size()<s2.size()) ? -1 : 1;/ (size is unsigned)

pg 591 /s/if (cmp_nocase(s,s2))/if (cmp_nocase(s,s2)== 0)/

pg 595 in f() s/int/string::size_type/ for each variable

pg 596 s/basic_string<Ch>& s2/const basic_string<Ch>& s2/

pg 596 s/Ch* p/const Ch* p/

pg 597 s/basic_string<Ch>& s2/const basic_string<Ch>& s2/

pg 599 s/19.4.4/19.4.6/

pg 601 s/ASCII characters/ASCII and similar character sets/

pg 601 s/'a'..'z' 'A'..'Z'/letter: 'a'..'z' 'A'..'Z' in C locale/

pg 601 s/'A'..'Z'/upper case letter: 'a'..'z' 'A'..'Z' in C locale/

pg 601 s/'a'..'z'/lower case letter: 'a'..'z' 'A'..'Z' in C locale/

pg 601 s/Use subscripting rather than iterators/Use at() rather than iterators and []/

pg 601 s/Use iterators rather than subscripting/Use iterators and [] rather than at()/

pg 603 s/20.3.10 and 20.3.10/20.3.9 and 20.3.10/

Chapter 21:

pg 616 s/>> (basic_istream<Ch,Tr>&,/>> (basic_istream<char,Tr>&,/ thrice

pg 616 s/If the state is good() or eof()/If the state is good()/

pg 617 s/When the state is fail()/When the state is fail() but not also bad()/

pg 620 s/from the usual char traits./from the usual char_traits for char./

pg 624 s/An ostream can be tied to at most one istream./A stream can have at most one ostream at a time tied to it./

pg 625 s/setstate(fail)/setstate(failbit)/

pg 629-630 Field width(n) applies to string and character <<operations as well as numeric <<operations. Thus, every example in sec21.4.4 and sec21.4.5 must be modified so that they don't have a character output operation "cout <<'('" before the numeric output operations for which the "width(4)" was intended. (recent standards clarification).

pg 633 s/and presented in <iomanip>./. Manipulators taking io_base are presented in <ios>. Manipulators taking istream and ostream are presented in <istream>, and <ostream>, respectively, and also in <iostream>. The rest of the standard manipulators are presented in <iomanip>./

pg 634 s/str.unsetf/s.unsetf/ twice

pg 634 s/cout <<setw(4) <<setfill('#') <<'(' <<12/cout <<'(' << setw(4) << setfill('#') << 12/ (recent standards clarification)

pg 638 s/is_open();/is_open() const;/

pg 640 s/ios_Init/ios_base::Init/

pg 640 s/ios::Init/ios_base::Init/

pg 640 s/ios_base::count/ios_base::Init::count/

pg 645 s/mane char_type/make char_type/

pg 648 s/traits_type::eof/traits_type::eof()/

pg 655 13. s/sec21.10[8]/sec21.10[12]/

pg 655 14. s/sec21.10[9]/sec21.10[13]/

pg 656 26. s/display/a display() operation/

Chapter 22:

pg 669 s/23/32/

pg 671 change f() to

	void f(valarray<double>& d)
		slice_array<double>& v_even = d[slice(0,d.size()/2,2)];
		slice_array<double>& v_odd = d[slice(1,d.size()/2,2)];
		v_odd *= 2;		// double every odd element of d
		v_even = 0;		// assign 0 to every even element of d

pg 677 s/23/32/

Chapter 23:

Chapter 24:

pg 751-754 The examples using an enabling condition are wrong. I forgot to apply DeMorgan's law when I transcribed the examples from an

	if(A&&B) throw C();
form to
	Assert(!A || !B);
erroneously and confusingly writing
	Assert(A && B);
For example, String::check() on pg 752 should be
	inline void String::check()
		Assert<Invariant>(!string_check || (p && 0<=sz && sz<TOO_LARGE && p[sz]==0));
and g() on pg 753 should be
	void g(int* p, exception e)
		Assert(!g_check || p!=0, e);							// pointer is valid
		Assert(!g_check || (0<*p&&*p<=g_max),Bad_g_arg(p));	// value is plausible
		// ...
In places, the commentary reflects the confusion.

Chapter 25:

Appendix A:

pg 806 add "Declaring a valiable register is a hint to the compiler to optimize for frequent access; doing so is redundant with most modern compilers."

pg 813 s/A.10.1/A.11/

Appendix B:

pg 822 s/m1/m2/ for second occurrence of m1

pg 822 s/_basic suffix/basic_ prefix/

Appendix C:

pg 831 s/basic C++ basic source/C++ basic source/

pg 832 s/&us/&uc/

pg 832 s/pus =/puc =/

pg 840 s/22.4.7/22.4.6/

pg 842 s/use v.s if v.t==S; use v.i if v.t==I/use v.s if t==S; use v.i if t==I/

pg 855 s/Xrefd<Record,map> x1/Xrefd<Record,set> x2/

pg 856 s/TT<i>/T<I>/

pg 857 s/f1(/f2(/ for the second f1

pg 860 s/is Consider/Consider/

pg 861 s/f(T a)/T f(T a)/ s/g(1);/return g(1);/

pg 862 s/f(T a)/T f(T a)/ and add /return a;/ to f()

pg 866 s/List<glob>::sort()/List<Glob>::sort()/


Chapter 1:

Chapter 2:

pg 31 s/rep stacks/Rep stacks/

pg 31 s/Stack::rep/Stack::Rep/

pg 33 s/p = new char[s];/v = new char[s];/

pg 33 s/delete[] p;/delete[] v;/

pg 35 s/Array_Stack/Array_stack/

pg 36 s/Array_Stack/Array_stack/ twice

pg 36 s/List_Stack/List_stack/ twice

pg 38 s/general type shape./general type Shape./

Chapter 3:

pg 46 s/is newline character/is the newline character/

pg 61 s/input_iterator/istream_iterator/ thrice

pg 61 s/output_iterator/ostream_iterator/

pg 63 s/shape/Shape/ six times

pg 65 s/int i =/double d =/

Chapter 4:

pg 71 s/implicitly converted bool/implicitly converted to bool/

pg 74 s/Chosing/Choosing/

pg 79 s/point;/Point;/

pg 81 s/one - 1)./one (1)./

pg 82 s/(sec8.2)/(sec8.2)./

Chapter 5:

pg 89 s/vector elements/array elements/

pg 97 s/i = 2;/i = 2/

Chapter 6:

pg 124 s/~ >>/~, >>/

pg 136 s/single variable./single variable or const./

pg136 s/unless the use explicitly/unless the user explicitly/

Chapter 7:

pg 147 s/};/}/ at the end of f()

Chapter 8:

pg 173 s/The arrows represents/The arrows represent/

pg 187 s/range_error/Range_error/

Chapter 9:

Chapter 10:

pg 223 s/tend to be easier/tends to be easier/

pg 226 s/};/}/ at the end of timewarp()

pg 230 s/m++/y++/

pg 239 s/fill2(/fill(/

pg 245 s/trice/thrice/

pg 258 s/intset/Intset/

pg 258 s/Expr::Eval/Expe::eval/

Chapter 11:

Chapter 12:

pg 321 s/Ival_islider/Ival_slider/

Chapter 13:

pg 328 s/so are the key operations/and so are the key operations/

pg 328 s/and that an argument C of type type will be used/and that a type argument C will be used/

Chapter 14:

Chapter 15:

Chapter 16:

pg 433 s/21.3.1/21.2.1/ for ostream

pg 433 s/character type/character classification/

pg 438 s/Link* put()/void put(Link*)/

pg 441 s/and code examples/and code examples,/

pg 433 s/Chapter 18/Chapter 19/

Chapter 17:

pg 463 resize() is for vector, list, and deque only

pg 469 s/!=, <, etc./!=, >, etc/

pg 506 s/The hash functions/The hash function/

Chapter 18:

Chapter 19:

pg 577 [1] s/the algorithm the operators/the algorithm using the operators/

Chapter 20:

pg 582 s/16.3.1/16.3/

pg 591 s/(sec13.4)/sec13.4/

pg 596 s/size_type, i/size_type i/

pg 597 s/typeder/typedef/

pg 602 s/(20.3.13)/20.3.13/

Chapter 21:

pg 625 s/to prove/to provide/

pg 638 s/is like a ofstream/is like an ostream/

Chapter 22:

Chapter 23:

Chapter 24:

Chapter 25: