Errata
The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".
The following errata were submitted by our customers and approved as valid errors by the author or editor.
Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update
Version | Location | Description | Submitted By | Date submitted | Date corrected |
---|---|---|---|---|---|
Page xiv 3rd paragraph |
"As of this writing, most compilers support C99 plus or minus a few caveats; the long double type seems to cause a lot of trouble, for example." The long double type is not a new feature in C99. It was introduced by the 1989 ANSI C standard, if not earlier. The only implementation I know of that has trouble with long double is MinGW, because it combines the gcc compiler with the Microsoft runtime library. Both handle long double consistently, but they give it different sizes, making the combination inconsistent. Note from the Author or Editor: |
Keith Thompson | Nov 22, 2014 | May 15, 2015 | |
Mobi | Page location 3154/13446 (22%) A command line above last paragraph in "Merging" subsection of "Trees and Their Branches" section of Chapter 4. Version Control |
To delete the side branch one doesn't use "git delete other_branch", but "git branch -d other_branch" or it's stronger version "git branch -D other_branch" ("git branch -d --force other_branch" in latest git version) if the other_branch was not merged into current one. There is no "git delete" command. Note from the Author or Editor: |
Jakub Narębski | Mar 14, 2015 | May 15, 2015 |
Mobi, Other Digital Version | Page location 10009/13446 (73%) Example 11-23. The group_s object. (groups.w), paragraph starting with "@ I played around a lot with different rules,..." |
"The standard distance is the $L_2$ norm, aka Euclidian distance, meaning that the distance between $(x_1, y_1)$ and $(x_2, y_2)$ is $\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}$. This is $L_3$, $\sqrt[3]{(x_1-x_2)^3+(y_1-y_2)^3}$." The definition of $L_3$ norm in two dimensions lacks absolute value sign, namely to be a norm the equation for it needs to take absolute value of difference between components, namely $\sqrt[3]{|x_1-x_2|^3 + |y_1-y_2|^3}$ This does not matter for $L_2$ (Euclidian) distance because (x_1-x_2)^2 is positive, and symmetrical change 1 <-> 2. This doesn't matter for code, because it uses Apophenia library: apop_vector_distance(g->position, position, .metric='L', .norm=3). Note from the Author or Editor: |
Jakub Narębski | Mar 21, 2015 | May 15, 2015 |
Safari Books Online | IV In the "Some Logistics" section of the preface of the 2nd edition. |
This is minor, but since you mention "pedantic readers"... Shouldn't "misconstrued incorrectly" simply be "misconstrued"? In what way could a reader misconstrue something correctly? :-) -sk Note from the Author or Editor: |
sk | Sep 17, 2016 | |
Safari Books Online | Ch13 Section: "The GNU Scientific Library" |
"...writing down a distance function, wrapping it and all the relevant *metatdata* into..." metadata is spelled incorrectly. Note from the Author or Editor: |
Yung-Jin (Joey) Hu | Apr 16, 2017 | |
Safari Books Online | Ch12 Section: "Atoms" Code listing: "Example 12-6" |
In example 12-6 we are importing "openmp_getmax.c" from example 12-5 with the intent of using the function defined in "openmp_getmax.c" called `get_max()`. However, in code listing 12-6, `get_max_factors()` is used instead. I think in Example 12-6 we should be calling `get_max()` instead of `get_max_factors()`. Note from the Author or Editor: |
Yung-Jin (Joey) Hu | Apr 16, 2017 | |
Safari Books Online | Ch 1 Ch 1, Section "Using Makefiles", the "Your Turn" box. |
Ack! No, no, no. The printf statement in K&R, 1st edition is: printf("hello, world\n"); No caps. No punctuation besides a comma. (At least you didn't use an exclamation point.) Please. ;-) Note from the Author or Editor: |
Charles Sharp | Oct 01, 2018 | |
Safari Books Online | 1 Ch 1, Section "Using Makefiles", first "Usage:" bullet |
In the bullet, the text states: " If you are using GNU Make, you have the option of capitalizing the name to Makefile if you feel that doing so will help it to stand out from the other files." BSD make, Solaris make, and GNU make all have search orders. All three will use a lower-case named makefile before using the upper-case version (in the absence of a '-f' filename). We used to always use an upper-case named Makefile. That way, if a developer needed to run a couple of experiments, they could just copy the Makefile to makefile, make a few changes, try it out, and then delete it. This is guaranteed behavior stated in the man page. Note from the Author or Editor: |
Charles Sharp | Oct 01, 2018 | |
Safari Books Online | 1 Example 1-1 |
Linking with the math library (libm) for the referenced example doesn't appear to be necessary. I.e.: gcc erf.c -o erf -g -Wall -O3 -std=gnu11 Compiles with no errors or warnings. However, if the argument to 'sqrt' is set to an uninitialized variable, e.g.: int value; .....sqrt(value).... the compilation invocation *does* generate an error.('undefined reference'). Adding the lm flag corrects the problem. It appears the compiler is optimizing beyond what one might expect. gcc version: gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 Note from the Author or Editor: |
Mark Kohalmy | Apr 25, 2019 | |
Page 7 command line at the bottom: ./configure --host=ming32 |
is command line: ./configure --host=ming32 should be: ./configure --host=mingw32 Note from the Author or Editor: |
Anonymous | Nov 20, 2014 | May 15, 2015 | |
Page 17 3rd |
in the section where he talk about makefile variables or command line variables , the part where he said: " All of these means are equivalent, as far as your makefile is concerned, with the exception that child programs called by make will know new environment variables but won’t know any makefile variables. " i think this is not right , the command line makefile variables will be visible to any child programs called by make as any new environment variables , let take an example: if i call make from the command line like this: make CFLAGS="-g -Wall" and inside the makefile : $(P): echo $(CFLAGS) the result will be displaying "-g -Wall" on the screen . so the value of CFLAGS is visible to echo even it's set on the command line when calling make which make it makefile variable and here echo will be the child program . so i think that this exception is wrong . Note from the Author or Editor: |
karim reefat | Jan 17, 2020 | ||
Page 18 Last paragraph before the "The Rules"-section |
The description of $< is incorrect. $< is the first prerequisite for the rule in question. It doesn't matter if that file has been modified or not. $? on the other hand are *ALL* the prerequisites that are newer than the target. See e.g. https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html This should demonstrate the difference: $ cat makefile foo: bar baz qux @echo First prerequisite: $< @echo Newer than target: $? @touch $@ $ touch bar baz qux $ make First prerequisite: bar Newer than target: bar baz qux ("foo" is now up to date, but touch one or more of the files and the rule has to be executed again.) $ touch qux $ make First prerequisite: bar Newer than target: qux Note from the Author or Editor: |
Povl Ole Haarlev Olsen | Feb 14, 2016 | ||
Page 18 3rd |
the line : " gram name, darn it—but the oddness aside, you can see that it took little setup within " the statement : " but the oddness aside " should be: " put the oddness aside " 'p' instead of 'b' Note from the Author or Editor: |
karim reefat | Jan 27, 2020 | ||
Page 20 1st (real) paragraph and the preceding/following single lines. |
You forgot to mention the "-c" option, without which cc/c99/gcc will try to make an executable, not an object file. Luckily, make doesn't forget to add the "-c" option, if you ask it to build an .o file: $ cat makefile P=program_name OBJECTS= CFLAGS = -g -Wall -O3 LDLIBS= CC=c99 $(P): $(OBJECTS) $ touch program_name.c $ make -n program_name.o c99 -g -Wall -O3 -c -o program_name.o program_name.c Note from the Author or Editor: |
Povl Ole Haarlev Olsen | Feb 14, 2016 | ||
Page 25 Last sentence before section "Using Libraries from Source" |
There is a suggestion to set LDLIBS=-L/usr/local/lib -Wl,R/usr/local/lib. My ld command claims the -R is an unknown option. Page 16 (my PDF) shows how to use the -R flag with the LDADD variable. Is this what you really meant on page 25? It worked for me when I changed LDLIBS to LDADD, and then also used the LDLIBS= -L/usr/local/lib -lgsl -lgslcblas -lm. Note from the Author or Editor: |
Paul Glezen | Apr 11, 2016 | ||
Printed | Page 44 top line (undisp 3) |
"Stop the display the of display item 3." Need to remove the second "the". Note from the Author or Editor: |
Rick Ward | Nov 30, 2016 | |
Printed | Page 55 Note 3 |
"The GLib test harness provides some extra assertion macros, like the string comparison macro, g_assert_compstr, used here." macro should be g_assert_cmpstr Note from the Author or Editor: |
Rick Ward | Nov 30, 2016 | |
Page 83 Figure 3-1 summarizes the story as a flow diagram. |
In "Figure 3-1 summarizes the story as a flow diagram." the flow diagram starts with "Automake.am". I suppose this should be "Makefile.am" as the text talks about Makefile.am? Note from the Author or Editor: |
Christoffer Holmstedt | Jun 16, 2015 | ||
Printed | Page 110 Example 5-1 |
I was not able to compile the code in dynamic.c. This was due to the use of the strcmp() used on line 20 and <string.h> not being included in the header. Note from the Author or Editor: |
Artagan Malsagov | Nov 12, 2020 | |
Page 124 Part 2 introduction, paragraph concerning chapter 12 |
"The secret is in parallel threads, and Chapter 12 covers covers three systems for turning [...]" should be "The secret is in parallel threads, and Chapter 12 covers three systems for turning [...]" Typo: "covers" written twice. Note from the Author or Editor: |
Christoffer Holmstedt | Jun 16, 2015 | ||
Printed | Page 127 2nd paragraph |
"When a program runs across this declaration in your code: int *a_pointer; the program will only do one of the above steps: * declare that an_array is a pointer" ====== I think it should say "declare that a_pointer is a pointer". Note from the Author or Editor: |
Anonymous | Oct 23, 2014 | May 15, 2015 |
Printed | Page 129 Bottom paragraph |
** ignore my previous errata, which contained an error ** "Python generally copies scalars but aliases lists (unless you use copy or deepcopy." This is a bit pedantic, but strictly speaking Python aliases scalars: i = 1 j = i assert i is j It's true that incrementing i won't affect the value of j, so that they behave as if j were a copy, but that's because scalars are immutable, meaning that the increment operation changes where the reference points rather than changing the value of the referenced object: old_id = id(i) i += 1 assert i == 2 assert j == 1 assert id(i) != old_id assert id(j) == old_id Note from the Author or Editor: |
Ben Plommer | Nov 17, 2014 | May 15, 2015 |
ePub | Page 185 discussion following directions NORTH SPUTH EAST WEST enum |
The sections weighing pros/cons of enums vs strings mistakenly assume that 8-bit instructions would execute faster than 16-bit instructions. While a narrower bit width could in theory be executed faster, in practice modern computer architectures tend to schedule instructions under a uniform clock rate. So manipulating a 1, 2, 4, 8, 16, 32, or 64 bit structure on modern computers will all use the same clock time. This happens even with variable length instructions: Chip makers have learned to convert Intel code to RISC-like implementations behind the scenes. On the other hand, it is true that fewer bits save more space, and load time may be significant in the context of arrays of 8-bit vs 16-bit numbers. But in general, enums are considered an extremely efficient and safe tool for modelling categorical things. Note from the Author or Editor: |
Andrew Pennebaker | Nov 25, 2016 | |
Printed | Page 187 Example 9-3, first comment |
In the first comment of Example 9-3 in the 2nd Edition, First Release, the comment beginning "/* The declaration, to put into a .h file..." runs past the right-hand margin and to the edge of the page. Some of the comment seems to be missing. Note from the Author or Editor: |
Kevin Zembower | Mar 20, 2015 | May 15, 2015 |
Printed | Page 218 2nd paragraph (Warning) |
s/unit/uint/ "Formally, the C standard only reserves int..._t and unit..._t" should read "Formally, the C standard only reserves int..._t and uint..._t" -- Guy Shaw Note from the Author or Editor: |
Guy Shaw | Apr 04, 2015 | May 15, 2015 |
Printed | Page 219 2nd to last paragraph |
"typdeffed" in first sentence presumably should be "typedefed", as in second sentence. Note from the Author or Editor: |
Ben Plommer | Dec 12, 2014 | May 15, 2015 |
Printed | Page 224 footnote 3 |
Footnote leaves off in the middle of a sentence. "[...] compiler doesn't support it, via" Note from the Author or Editor: |
Matt Steadman | Jun 23, 2015 | |
PDF, ePub | Page 227 Footnote 3 (PDF), Footnote 23 (epub) - last sentence |
The footnote stops in the middle of a sentence by the looks of it. "[...] then have the C preprocessor define __attribute__ to be blank should Autoconf find the user’s compiler doesn’t support it, via" Note from the Author or Editor: |
Christoffer Holmstedt | Jun 17, 2015 | |
Printed | Page 237 1st paragraph |
"In this example to to recurse through a directory..." should be "In this example to recurse through a directory..." duplicate "to". Note from the Author or Editor: |
Anonymous | Jul 02, 2017 | |
ePub | Page 334 5th paragraph in the chapter 'Unicode Libraries' |
The line “Recall that 8 bytes is not nearly enough to express all characters in one unit, so a single character is between one and six units long.” should probably read “Recall that 8 bits is not nearly enough to express all characters in one unit, so a single character is between one and six units long.” Note from the Author or Editor: |
Mario Landgraf | Nov 05, 2014 | May 15, 2015 |
Page 336 token |
I think that it's just small typo. There is no such function as "strtok_n". The C Standard defined strtok and POSIX strtok_r. My sugeestion is to rewrite this sentence as: "into tokens; strtok and strtok_r are designed for this" Note from the Author or Editor: |
Grzegorz Szpetkowski | Dec 20, 2014 | May 15, 2015 | |
Printed | Page 339 Line 26 |
nyt_feed.c, Line 26 of page 339 (also line 45 of the listing downloaded from the github repository): char *rss_url = "h t t p : // rss.nytimes.com/services/xml/rss/nyt/HomePage.xml"; should read char *rss_url = " h t t p s : // rss.nytimes.com/services/xml/rss/nyt/HomePage.xml"; [sorry about the extra spaces, but the errata system will not allow URL's!!] In recent years it has become fashionable to only serve up the encrypted https flavour of your web pages. Requests for the insecure http flavour will either be re-directed to the https version or, as in this case, fail. There is a (trivial) pull request waiting for you on git hub :-) Note from the Author or Editor: |
bl4krat | Sep 04, 2020 | |
Printed | Page 345 Appendix A - C101 - The Structure |
Further to Charles Sharpe's errata dated 1 Oct 2018: K&R's program to say 'hello' still only uses lower case and a comma, so you may want to correct the first listing in the C-primer too. Change: <code>printf("Hello, world.\n");</code> To: <code>printf("hello, world\n");</code> Note from the Author or Editor: |
bl4krat | May 13, 2020 | |
Page 351 3rd paragraph |
"Some things are surprisingly easy thanks to the array nature of strings. Given char* str="Hello"; you can turn a Hello into Hell by inserting a NUL character: str[4]='\0';" This is violation of 6.4.5/7 subclause (String literals) according to C11 Standard (referring to N1570 draft) as well as by previous C99 and C89 Standards. The result is undefined behaviour: "If the program attempts to modify such an array, the behavior is undefined." The valid way would be to replace string literal with string array like: char str[]="Hello"; // the number of elements is guessed by initializer. Note from the Author or Editor: |
Grzegorz Szpetkowski | Dec 17, 2014 | May 15, 2015 | |
Safari Books Online | 351 Code segment on the bottom of the page |
strncpy(str2, 100, str1); strncat(str2, 100, str1); should be: strncpy(str2, str1, 100); strncat(str2, str1, 100); Note from the Author or Editor: |
Anonymous | May 10, 2015 | May 15, 2015 |
Page 353 Appendix A: C 101 - page 353 - 8th paragraph |
in the paragraph: You saw another example several times above: in the evaluation of printf("hello\n"), the expression is replaced by a zero on success, but the evalua‐ tion is useful for the side effect of changing the state of the screen. the part when he said: the expression is replaced by a zero on success, i think that expression printf("hello\n") will be replaced by the number 6 not zero because printf On success it will return the total number of characters not just zero. Note from the Author or Editor: |
karim reefat | Aug 20, 2019 |