This lists all known errors in
The C Programming Language, Second Edition,
by Brian Kernighan and Dennis Ritchie
(Prentice-Hall, 1988).
The first printing of the book was made before the Standard was finalized; these copies say "Based on Draft-Proposed ANSI C" on the front cover. All subsequent printings are identified by a large red ``ANSI C'' on the right center of the cover. Fortunately, the changes are minor; some repair our bugs, a few account for last-minute changes in the draft standard. These changes were made so early that they probably do not apply to you.
Two or three sentences in the Preface and Introduction are updated to describe the state of the Standard.
atof is in stdlib.h, not math.h; this changes pages 71, 76, 82, 121.
On page 86, error corrected: missing automatic initializers are zero too.
On page 168: changed 1 to 1.0 to avoid potential overflow.
Minor typos are corrected on pages 87, 89, 164, 165, 168, 180.
The inconspicuous references to noalias on pages 192 and 211 are removed.
The following paragraph is added to the end of section A6.6 (page 199):
``A pointer may be converted to another pointer whose type is the same except for the addition or removal of qualifiers (A4.4, A8.2) of the object type to which the pointer refers. If qualifiers are added, the new pointer is equivalent to the old except for restrictions implied by the new qualifiers. If qualifiers are removed, operations on the underlying object remain subject to the qualifiers in its actual declaration.''
On page 199, beginning of section A6.8, ``Any pointer may be converted to type void *...'' is changed to ``Any pointer to an object may be converted to type void *...''.
On page 204, A7.4.4, ``The operand of the unary + operator must have arithmetic or pointer type...'' should read ``must have arithmetic type...''.
On page 206, A7.9, about relational operators: ``Pointers to objects of the same type may be compared...'' is changed to ``Pointers to object of the same type (ignoring any qualifiers) may be compared...''.
The indented material on page 209, ``According to the restrictions... relaxing it.'' is removed. [This is related to the paragraph added above. The wording of the penultimate draft made it useless to take an (int *) pointer, cast it to (const int *), then cast it back to (int *).]
On page 219 middle, initialization of structures, add ``Unnamed bit-field members are ignored, and are not initialized.''
Appendix B changes:
p 242: Add ``fflush(NULL) flushes all output streams.'' to fflush description.
p 243: Change to ``it must be called before reading, writing or any other operation'' in setvbuf description.
p 249: Add ``Comparison functions treat arguments as unsigned char arrays.'' to string.h description.
p 255: Change range of tm_sec to (0,61) for leap seconds.
p 255: Change CLK_TCK to CLOCKS_PER_SEC.
p 257: Drop U and L suffixes from limits.h constants. tm_sec range is (0,61) here too.
Appendix C change:
p 261: Change ``External declarations without any specifiers...'' to ``External data declarations without any specifiers...''.
The index has been reprinted to fix a couple of typos and account for motion within Appendix A; one page of the table of contents is changed.
A later printing in October, 1989,
made minor changes on page 131 to add & to the last
example, on page 208 to change ``equal'' to ``unequal'' in
the description of logical OR, and on page 254 to clarify
that only volatile automatics are saved with longjmp.
The following errors have not yet been fixed in any printing.
41: The loop at the bottom of the page is functionally equivalent to the one on page 29, but not identical in form, as is implied by the text.
44: 1U is an unsigned int, not an int.
49: In the discussion of shift operators, `which must be positive' should be `which must be non-negative'.
53: Note under the table should say & as well as + - * has higher precedence as a unary operator.
111: Indent is too large, and a bit of program text is cut off.
114: quote missing in "Jan, near top of page.
142: The remark about casting the return value of malloc ("the proper method is to declare ... then explicitly coerce") needs to be rewritten. The example is correct and works, but the advice is debatable in the context of the 1988-1989 ANSI/ISO standards. It's not necessary (given that coercion of void * to ALMOSTANYTYPE * is automatic), and possibly harmful if malloc, or a proxy for it, fails to be declared as returning void *. The explicit cast can cover up an unintended error. On the other hand, pre-ANSI, the cast was necessary, and it is in C++ also.
143: strdup is not indexed.
164, 165: (text and code) fputs returns EOF on error, non-negative for OK.
167: [the return value of malloc or calloc] "must be cast into the appropriate type" is incorrect as stated. See the remarks just above for p. 142.
193: If an integer constant is suffixed with UL, it is unsigned long.
195: To the list at the start of section A4, "Identifiers, or names, refer to a variety of things...", add labels as well.
229, 239: Syntax: the argument list is optional in macro definitions with parentheses.
231: Extra right parenthesis in nested call to cat macro.
244: In table B-1, the argument corresponding to x, X is unsigned int.
245: The scanf functions do not ignore white space in formats.
245: vprintf, vfprintf, vsprintf return int.
246: First argument of sscanf should have type const char *.
249: In the description of strncpy, t should be ct.
210: In section 8.1, it is said that a register object cannot have the & operator applied `explicitly or implicitly,' which is true, but needs an amplifying clause to show that the implicit & comes from mention of an array name, so declaring an array as a register is fruitless.
There is no mention of the offsetof macro.
Index: stddef.h is listed but not described in the text. char,double,long, short are on page 9, not page 10. sizeof is on 242, not 247. ``byte'' is not indexed.
Updated Oct 1 2000
Copyright © 1998
Lucent Technologies. All rights reserved.