Morgan Stanley | Columbia University | Churchill College, Cambridge

home | C++ | FAQ | technical FAQ | C++11 FAQ | publications | WG21 papers | TC++PL | Tour++ | Programming | D&E | bio | interviews | videos | applications | glossary | compilers

Errata for 5th/15th printing of The C++ Programming Language

Modified August 23, 2002

Errata for Bjarne Stroustrup: The C++ Programming Language (special edition), Addison-Wesley, 2000. ISBN0-201-70073-5. Errata for the 5th printing yielding the 6th printing.. Also for the 15th printing of "The C++ Programming Language (3rd edition)" yielding the 16th printing..

Errors and Clarifications

Chapter 1:

pg 13 s/(sec B.2)/(with a few minor exceptions; see sec B.2)/

Chapter 2:

Chapter 3:

pg 62 s/we search that list/we search that sequence/

Chapter 4:

pg 77 Replace the 5th paragraph with: "An enumerator can be initialized by a constant-expression (C.5) of integral type (4.1.1). When all enumerators are non negative, the range of the enumeration is [0:2^k-1] where 2^k is the smallest power of two for which all enumerators are within the range. If there are negative enumerators, the range is [ -2^k:2^k-1]. This defines the smallest bit-field capable of holding the enumerator values using the conventional two's complement representation. For example:"

pg 80 s/* kings[] is a vector/* kings[] is an array/

Chapter 6:

pg 121 At the bottom of the page add the paragraph: " Before applying the grammar rules, lexical tokens (A.3) are composed from characters. The longest possible sequence of characters is chosen to make each token. For example, && is a single operator, rather than two & operators, and a+++1 means (a++)+1."

pg 134 s/``does p point to a valid object,''/ ``does p point to a valid object (assuming proper initialization),''/

Chapter 8:

pg 167 s/string string_value;/std::string string_value;/

pg 190 A better Error:

	namespace Error {
		int no_of_errors;

		struct Zero_divide {
			Zero_divide() { no_of_errors++; }

		struct Syntax_error {
			const char* p;
			Syntax_error(const char* q) { p = q; no_of_errors++; }

pg 192 remove all mention on no_of_errors

pg 193 s/Driver::no_of_errors;/Errorr::no_of_errors;/

Chapter 9:

pg 210 main.c should #include< iostream>

Chapter 10:

pg 251 replace the middle example with

	void g()
		vector< Table> v(10);					// no need for a delete
		vector< Table>* p = new vector< Table>(10);	// use plain "delete" rather than "delete[]"

		delete p;
Using a container, such as vector, is simpler than writing a new/delete pair. Furthermore, vector provides exception safety (Appendix E).

Chapter 11:

pg 288 /to every element of the array/to every element of the vector/

pg 290 replace the example using Y at the middle of the page by: "Given a class Y for which ->, *, and [] have their default meaning and a Y* called p then

	p->m == (*p).m		// is true
	(*p).m == p[0].m	// is true
	p->m == p[0].m		// is true

pg 293 make class Cref a private member of class String

Chapter 13:

pg 332 Replace the top example by

template< class T, int max> class Buffer {
	T v[max];
	Buffer() { }
	// ...

Buffer< char,128> cbuf;
Buffer< int,5000> ibuf;
Buffer< Record,8> rbuf;

pg 335 s/const char[12]/const char v[12]/

pg 337 Replace last call by

	max(2.7,4);	// max(2.7,4)
Chapter 14:

pg 369 better:

	X* p3 = new(&buffer[10]) X;		// place X in buffer (no deallocation needed)
	X* p4 = new(&buffer[11]) X[10];

Chapter 16:

pg 433 correct entry in Input/Output table:

	< cctype>	character classification functions	sec20.4.2

pg 459 s/set of containers/set of iterators/ in 8.

Chapter 17:

pg 464 /bidirectional operator/bidirectional iterator/ on last line

pg 500 s/hashmap/typename hashmap/ in the return type of the definition of operator[]

pg 502 s/&v[i]/v.begin()+i/

pg 503 A better string specialization:

template < > size_t Hash< string>::operator()(const string& key) const
	size_t res = 0;

	typedef string::const_iterator CI;
	CI p = key.begin();
	CI end = key.end();

	while (p!=end) res = (res<<1)^*p++;	// use int value of characters
	return res;

Chapter 18:

pg 535 the sort should be "off.sort(Person_lt);"

pg 538 replace the second example with

For a call random_shuffle(b,e,r), the generator is called with the number of elements in the sequence as its argument. For example, for a call r(e-b) the generator must return a value in the range [0,e-b). If My_rand is such a generator, we might shuffle a deck of cards like this:

	void f(deque< Card>& dc, My_rand& r)
		// ...

Chapter 19:

pg 570 add "template":

	typedef typename A:: template rebind< Link>::other Link_alloc;	// allocator< Link>

pg 573 s/an implementation of a standard may take advantage of that./ an implementation of a standard container may take advantage of that./

Chapter 20:

pg 581 s/The difference is .../The difference is that move() works correctly even if [s,s+n[ and [s2,s2+n[ overlap./

pg 582 s/wstreamoff/streamoff/

pg 582 s/Such functions are most easily utilized/ Such instructions are most easily utilized/

pg 599 replace the last two declarations with:

	size_t strspn(const char* p, const char* q);	// number of char in p before a char not in q
	size_t strcspn(const char* p, const char* q);	// number of char in p before a char in q

Chapter 21:

pg 637 add "#include" to the first example of 21.5.1

pg 638 s/cerr/std::cerr/

Chapter 22:

pg 660 s/1+epsilon-1 is representable/1+epsilon-1 is larger than 0/

pg 665 better:

	valarray shift(int i) const;	// logical shift (left for i< 0, right for 0< i)
	valarray cshift(int i) const;	// cyclic shift (left for i< 0, right for 0< i)
pg 670 s/one-past-the-end of the valarray./one-past-the-end of the slice./

pg 673 better:

	slice_array row(size_t i) { return (*v)[slice(i,d1,d2)]; }	// error

Chapter 24:

pg 754 Better first sentence: "I often find it simpler to write ordinary code to check arguments and results than to compose assertions."

Chapter 25:

pg 769 s/one-word space overhead/one-word-per-object space overhead/

pg 778 Better:

	template< class T> class Vector< T*> : private Vector< void*> {
		typedef Vector Base;

		Vector() {}
		Vector(int i) : Base(i) {}

		T*& operator[](int i) { return reinterpret_cast< T*&>(Base::operator[](i)); }

		// ...

Appendix A:

Appendix B:

pg 817 s/Direction d = 1;/enum Direction d = 1;/

Appendix C:

pg 895 s/: num_put/std::num_put/

pg 898 s/my_numpunct/My_punct/

pg 910 add before D.4.4.4: A _byname version (D.4, D.4.1) of time_put is also provided:

	template < class Ch, class Out = ostreambuf_iterator< Ch> >
	class std::time_put_byname : public time_put< Ch,Out> { /* ... */ };

pg 912 s/time_put()/time_put::put()/ twice

pg 912 replace the last paragraph with: A _byname version (D.4, D.4.1) time_get is also provided:

	template < class Ch, class In = istreambuf_iterator< Ch> >
	class std::time_get_byname : public time_get< Ch,In> { /* ... */ };

pg 915 s/Date_format< char>::/Date_format::/

pg 918 s/dateorder()/date_order()/

pg 919 s/order = dateorder();/order = date_order();/

pg 919 s/tmp->tm_mday = val[1];/tmp->tm_mday = val[2];/

pg 924 s/widen(narrow('x')) == 'x'/widen(narrow('x',0)) == 'x'/

pg 926 s/out() encountered/in() encountered/

pg 928 add "char ch;" before the while-statement

Appendix D:

Appendix E:


Chapter 4:

pg 80 s/a vector/an array/

Chapter 12:

pg 307 s/manager/Manager/ twice in the comments

Chapter 17:

pg 488 s/the m/m/ on the first line

pg 505 s/a whether sentence//whether a sentence/

Appendix B:

Appendix D:

pg 817 s/Grenwich/Greenwich/

Appendix E:

Morgan Stanley | Columbia University | Churchill College, Cambridge

home | C++ | FAQ | technical FAQ | C++11 FAQ | publications | WG21 papers | TC++PL | Tour++ | Programming | D&E | bio | interviews | videos | applications | glossary | compilers