C Books and C++ Books You Don't Want ! Copyright © 1998-2012 All rights reserved by Yechiel Kimchi

The Age of Disinformation

Science School-Books.

The text begins: "Did you ever get the feeling that what you learnt in science class at high school was just plain wrong? Did you feel stupid because you couldn't understand what the textbook was getting at? Did you get a question wrong even when you'd faithfully applied the right formula?

Well, turns out you might have been right all along."

Oops... The above link died.

Here is a local copy found by the help of Google cache.



The above link died. Here is a local copy found by the help of cache. Teach yourself programming in Ten years! (Hebrew) Feb. 10, 2011



Bad Books about C and C++: Please read a review of a specific book and a general comment. (June 2, 2008)



This page owes its existence to my frustration of not having good books in Hebrew for teaching the C and C++ programming languages.

I really wish there were good books in Hebrew for those who are interested in studying C and/or C++. Alas, I haven't seen one. It is truly unfortunate.

Meanwhile, many of my students approached me, asking my opinion about some books in English. Not surprisingly, there were bad books among them too. Then, I have decided that when I have an opinion about a book, not necessarily in Hebrew, I will put it here - for the benefits of my students and any other interested person. Obviously, I am limited to the books that I can, at least, leaf through.

My sources are: The bookstores at the Technion and the University of Haifa, books that are sent to me by publishers, and books that are shown to me by students.

Books that I look at are divided to three categories:

The good ones (even "relatively good") - find their way to my C and C++ sources as a reference book, or as a text book at my Text Book List (each has a comment, stating strengths and weaknesses).

The bad ones - find their way here. I do not really read them, because I have specific criteria that make a book bad to my view - usually, exemplifying that the author (or whoever wrote a particular part of the book) has a misunderstanding of the programming language at question, or a misconception of basic programming techniques in that language. Then, I exemplify my findings with quotes from the book. Let me emphasize that the only reason I put books here, is to warn my students from learning from them - I consider these books a "risk" to my students' grades, if they base their answers at the exam on these books.

By the way, even the list of bad books in Hebrew is not complete. I have listed the most commonly known books (at least among the students that I meet), because I did not have the time to list EVERY BAD BOOK. I hereby announce, that every book in Hebrew about C and/or C++ that I have seen - belongs to this category.

Sorry.

to my view - usually, exemplifying that the author (or whoever wrote a particular part of the book) has a misunderstanding of the programming language at question, or a misconception of basic programming techniques in that language. Then, I exemplify my findings with quotes from the book. Let me emphasize that the only reason I put books here, is to warn my students from learning from them - I consider these books a "risk" to my students' grades, if they base their answers at the exam on these books. By the way, even the list of bad books in Hebrew is not complete. I have listed the most commonly known books (at least among the students that I meet), because I did not have the time to list EVERY BAD BOOK. I hereby announce, that every book in Hebrew about C and/or C++ that I have seen - belongs to this category. Sorry. All others, I just do not mention - they are not good enough to be recommended, and I have not found reasons which are good enough to justify public denunciation (namely, they are not that big "risk" to my students).

Disclaimer: The following is given as a service to my students in C and C++ courses, and to anyone interested in studying these programming languages. The opinions below are solely mine, and represent what I have learned about high quality programming (from my own experience, and by learning from many others). If you think I am mistaken in any of the items below, please inform me - and I will correct it (if you are right).

Notes:

New books are added to the list whenever I have the time.

I have a long list of comments on each book. I have given you only a few examples.

The errors I have found were not found by reading the books, but by leafing through them - there must be many more that I have not found.

Some of the books may have updated editions. I hope they have corrected some of the errors. Nevertheless, it would not change my opinion about the books, since I do not comment on typos or overlooked errors. My comments refer to basic knowledge of the programming languages and to basic knowledge of programming techniques. If the authors want to write a good book, they should not rewrite the old one - they should start from scratch.

Introduction

General Remarks about Bad Books

(not necessarily in Hebrew)

Many of the books do not care about the standard (ANSI), either for C or C++ . They do refer occasionally to the standard, but in their examples or subject matter, they never make a clear distinction between what is standard and what is not. In all cases I have noticed, they refer to the PC system and compilers (e.g, the size of an int is always two bytes).



or . They do refer occasionally to the standard, but in their examples or subject matter, they never make a clear distinction between what is standard and what is not. In all cases I have noticed, they refer to the PC system and compilers (e.g, the size of an is always two bytes). The books do not care about teaching good programming style. Wherever I look, I see too many global variables, functions which are too long, and ill-defined interfaces of various kinds.



In most cases, each book has its own style of program writing, and it is very hard to understand the structure of a code from the indentation. There seems to be a significant positive correlation between books that use explicitly structured and well indented code (usually, a minor variation on K&R style), and books that exemplify good programming style.



Too many books, even some that are otherwise reasonably good, use the type float instead of double . There is no reason to use float , unless you have millions of them, and you need to save memory on the expense of accuracy. Note, however, that according to the standard these types may be identical - so you may gain nothing. (When using external libraries, however, you should be aware of the fact that they may use the type float , whether justifiably or not, in their API, and you should find the right way to adapt your software to it.)

The type double is the C native type for floating point numbers, which is the reason why you should use it as your default choice. For example, the comparison x == 3.7

is guaranteed to succeed if you had double x = 3.7; before (see K&R2, p.198, A6.4, first sentence, that it always works).

But it is not guaranteed to succeed if you had float x = 3.7; .

The latter will surprise novices, which good textbooks should avoid. (Yes, I know, floating point comparison should be done with epsilon , but how do you show to second-week C students the way to solve a quadratic equation ?)



(for more information look at GNU's page about non-bugs in gcc and role down to (search for) floating point . They also direct you to David Goldberg's paper What Every Computer Scientist Should Know About Floating Point Arithmetics (PDF, and a local compact PS)





instead of . There is no reason to use , unless you have of them, and you need to save memory on the expense of accuracy. Note, however, that according to the standard these types - so you may gain nothing. (When using external libraries, however, you should be aware of the fact that they may use the type , whether justifiably or not, in their API, and you should find the right way to adapt your software to it.) The type is the for floating point numbers, which is the reason why you should use it as your default choice. For example, the comparison is guaranteed to succeed if you had before (see K&R2, p.198, A6.4, first sentence, that it always works). But it is not guaranteed to succeed if you had . The latter will surprise novices, which good textbooks should avoid. (Yes, I know, floating point comparison should be done with , but how do you show to second-week C students the way to solve a quadratic equation ?) (for more information look at GNU's page about non-bugs in gcc and role down to (search for) . They also direct you to David Goldberg's paper (PDF, and a local compact PS) Too many books, even some that are otherwise reasonably good, use the C MACRO assert() for sanity checks as part of the regular code. This is in contrast to the way assert() is #define d, and may jeopardize using assert() for what it meant to be: A DEBUGGING AID .

To make a long story short, suppose such a software is compiled with the definition of NDEBUG set on (e.g, with the flag -DNDEBUG set while compiling under gcc ), then the resulting executable is no longer valid. Moreover, any "guards" that will be put in the source-code to prevent such hazardous compilation - will prevent using assert() for REAL debugging.

Yet, the real problem in using assert() is its behaviour, which is to shut your program off .

I am sure you would not like to hear the following announcement during a trans-Atlantic flight: "Ladies and gentlemen, this is your captain speaking. You are kindly adviced

that our plain is going to ditch in the Atlantic Ocean. The computer system crashed

after my co-pilot had entered an impossible value for our latitude."





Read someone else's opinion about that matter. (June 2, 2008)

For a typical good review about a bad book look here. (June 2, 2008)

My reviews on the Internet

Reviews for ACCU. (June 2, 2008)

(June 2, 2008) Reviews for Amazon. (June 2, 2008)

Wrong Information on the Web is also too Common

Reading the information on this page reveals that the publisher (who sells e-books) is ignorant about basic features of C++ (and C).

This is an example of a "professional" discussion page, where the participants are clueless about the basics of C and C++.

Here is a good discussion page that denounces the above pages.

Books in English

Herbert Schildt: Any Book on C or C++ . Why ? Read this (Q-16, temporary link)

A future substitute - html version (different numbering, I did not check it yet Sep. 28, 2006)





Read an example-review for a specific book. (June 2, 2008)

I. Pohl: Object-Oriented Programming Using C++ 1997, 2nd ed. Addison-Wesley Longman

Why ? Read this review. (June 2, 2008)

H. M. Deitel & P. J. Deitel: C++ How to Program , 3rd ed. 2001, Prentice-Hall



This book used to be on my Text Books page, but I have always been hesitant about it. That book had the longest comment on it, and as mentioned in my comments page the shorter the comment is, the better I think of a book. The next paragraph is the original comment that I wrote for this book. My decision for including this book in my text-books page was that despite the shortcomings of it, it was not completely bad as many others, and most of all there were very few good books in the market. I may regret about my past decision in the future, but given the fact that nowadays there are a few more good books about C++, there is no doubt in my mind that it is now the appropriate time to put this book where it belongs - the bad-books section. This is the original comment:

" C++ How to Program " may help novices in C++ (especially when they lack previous programming experience, or even if they have no C background). Indeed, it combines very thorough explanations for basic constructs in C++ with a touch of more advanced features of the language. In addition, it gives many DO and DON'T rules, illustrated by many programming examples.

Unfortunately, despite the authors' prominence a few of the rules are misleading (or plainly wrong) - which novices cannot detect them. On top of that, many of the code examples are not of high quality (to put it mildly). Here are a few examples: General: assert is used for algorithmic error detecting instead of for debugging only . This is a serious error, common to many, otherwise good, books. But here it is very widely used. In many classes, data members are assigned in constructors, rather than being initialized.

This should be considered a potential bug (and sometimes it is indeed a syntax-error) and is almost always a redundant (sometimes severe) overhead. Here is a (partial) list of comments about class String , pp. 487-492: The two general problems, mentioned above, are exemplified. Relational operators ( ==, >, etc.) are asymmetric. { char *s = "abc"; String st(s); // Try their class String bool t1 = st == s, // o.k. t2 = s == st; // syntax error } operator! is defined - which is nice. But, in that case, operator bool should be defined. Otherwise you will need { String st("abc"); if (!st) { // Is String empty ? // ..... } if (!!st) { // Is String NOT empty ? // ..... } } Once operator bool is defined, there is no need for operator! Had setString returned a char * value, it could have been used in initialization list for the class constructors. operator<< uses a magic number with an unreasonable value. main() is 72 lines long. Want to read additional review (by someone else) ?

And finally, the authors do not reply to e-mail sent to them, concerning the quality of the book. Makes one wonders ...



" " may help novices in (especially when they lack previous programming experience, or even if they have no background). Indeed, it combines very thorough explanations for basic constructs in with a touch of more advanced features of the language. In addition, it gives many DO and DON'T rules, illustrated by many programming examples. despite the authors' prominence a few of the rules are misleading (or plainly wrong) - which novices cannot detect them. On top of that, many of the code examples are not of high quality (to put it mildly). Here are a few examples:

Alan R. Neibauer: Your First C/C++ Program 1994, ISBN-0-7821-1414-8



A Hebrew translation from English, by Ronen Eliav.

This one seems to be the worst C/C++ book ever translated to Hebrew :-(among the ones I have seen ;-) and one of the worst on this list.

The following are direct translations from the Hebrew edition of the book, and I hope it is not far from the original text in English. The meaning of the content in Hebrew was preserved in full.

The book claims that it teaches C and adds (special, boxed, Y.K.) comments that are relevant for C++. Most of citations below were taken from such "C++ Comments".

P. 9, C++ Comments: " Later on, you will learn that C++ is a kind of improved version of the C language. It means that if a C compiler can compile your program, so will a C++ compiler. "

What ??? (*)



P. 11, C++ Comments: " Remember that all information included in this book is related to both the C and C++ languages. Instead of explicitly mentioning C/C++ again and again, we shall usually refer to the C language only. It does not mean that you learn the C language only - you learn both languages at the same time. "

P. 17, What the C Language Can Do for You, and What It Cannot Do: " ... and once you have learn the C language, the transition to the C++ language is easy and simple. "

P. 24, C++ Comments: " The C language and the C++ language have identical structure. Once you learn how to write programs in C, you will know how to write programs in C++. "

P. 27: It says that return is a function

P. 251, C++ Comments: All that the book has to say about classes in C++ is exemplified in an example that is less than one page long.



What I have to say about it, I have already said somewhere else.

Here, let me put it as politely as possible:



DO NOT BELIEVE ANY OF THE STATEMENTS ABOVE.

Want to read additional review (by someone else) ? (June 2, 2008)

(*) There are MANY reasons that make a strictly conforming C program an illegal C++ program . Here is a very simple one, that after making it C++ correct (e.g, replace `new' by `New') will produce different output!!!

#include <stdio.h> int main() { int new = sizeof('a'); printf("sizeof('a') = %d

", new); return 0; }

Michael Smith: Object-Oriented Software in ANSI C++ 2nd ed. Publisher: McGraw-Hill .

Read my review (more general ( older version) link June 2, 2008) for ACCU.



P.59: The Chapter on Classes precedes the Chapter on Functions. P.64: No initializations in a Ctor. P.65: Bad coding-style at Account::withdraw(). (test yourself: think about both the function and its environment): float Account::withdraw( float money ) { if ( the_balance-money >= the_min_money ) { the_balance = the_balance - money; return money; } else { return 0.0; } } P.100: Uses #ifdef protection for implementation-file P.130: Uses exceptions, which are introduced 90 pp. ahead. P.257: What can be virtual and what cannot:

On top of redundancy, it forgets static functions. P.325: A Ctor with two parameters (and no default value(s))

is declared explicit P.402: Declare cin as a local variable

as a local variable Uses the type istrstream , which is designated depreciated .

, which is designated . The while loop control is buggy . P.415: A full Chapter-26 Using legacy C++ compilers .

I think it is appropriate to cite the Rational for the C-Standard:

"Existing code is important, existing implementations are not." P.468: References: Only four references

This may explain the author's poor knowledge. The fact that B. Stroustrup's book is there does not guarantee that it has been read

Angela B. Shiflet: Problem Solving in C++ . Publisher: PWS.



There is hardly inheritance in the book. P.537, P.768 Talking about overloading operator= (which is so important) in so few words, without a single example, or any reference to an example. P.810 Using assignment in constructor (rather than initialization). P.811 Funny code: boolean_t list::ListIsEmpty(void) { return (head == NULL ? TRUE : FALSE); } I am NOT going to tell you how this code should have been written. But there are AT LEAST three (in fact ) different things that should not have been here (either wrong or very bad style).

J. Hennefeld & C. Burchard: Using C++ . Publisher: PWS.



There is hardly inheritance in the book. There is hardly overloading in the book. P.159 C style for loops. P.533 void main() If you want to know why it is important to use int main() please look at Steve Summit's C-FAQ 11.14a 11.15

P.533 A List is built, consisting of links only, and without supporting functions. P.546 A list template is presented, only interface - no implementation. P.645 Examples of functions: The code is sloppy even by C coding standards (by no means this is a criticism of C , nevertheless, C++ has more constructs for better coding).

This means that the authors are not even aware of the constructs available in C for good coding style.

coding standards (by no means this is a criticism of , nevertheless, has more constructs for better coding). This means that the authors are not even aware of the constructs available in for good coding style. The function round() has a BUG

Steven C. Lawlor: Computer Science with C++ . Publisher: PWS.



NO inheritance at all. NO overloading in the index (probably none at all). P.240 class Employee with public data . P.240 Constructor uses assignments, not initializations.

SAMS Teach Yourself: C++ in 21 days . Publisher: SAMS.



Above all I strongly object to the title of the book that too many people will take seriously. See what Marshal Cline has to say about that. P.363 - 365 class String No initializations in Ctors (and also in many other classes).

(and also in many other classes). Code duplication in operator= and copy Ctor .

and . Funny Dtor

The two (correctly set) operator[] suffer from code duplication AND bad coding style.

suffer from code duplication AND bad coding style. Code duplication for operator+ and operator+=

and operator+= returns void AND bad coding style.

returns AND bad coding style. operator+ is not symmetric (using friend is unnecessary, and nevertheless, friend is introduced much too late).

is not symmetric (using is unnecessary, and nevertheless, is introduced much too late). The type for the length of the string should have been defined using typedef ( because it is not an int ). P.366 In function main() Clumsy code.

Why there is no operator<< for class String ? P.445 The Shape class hierarchy is a design error in various aspects. P.482 class Employee uses getFirstName(), setFirstName() etc. instead of using function overloading. P.517 class String (again) with two versions of operator+ , which are ambiguous (AND code duplication).

SAMS Teach Yourself: C in 21 days . 5th ed. Publisher: SAMS. ISBN 0-672-31766-4

Read my review (more general) for ACCU.

Still Under Construction.

A reader review I had sent to Amazon



I will soon add coding examples (the following are comments on a previous edition).

Above all I strongly object to the title of the book that too many people will take seriously. It takes at least two weeks learn and understand the full syntax of C and its intended meaning. But you are definitely NOT a C programmer, yet. Having experience in other languages, may shorten the time for understanding the syntax, but then, you will have to unlearn quite a few things before you become a C programmer. See what I have said before. The book is full of errors, I'll give you a (short) list of examples in the near future. (from an older edition) P. 572 - 575 The following two are enough to disqualify a book about C : Using magic numbers instead of using #define .

instead of using . Using the library function gets() instead of fgets() .



Greg Perry: C by Example . Publisher: Que [for Macmillan USA]. ISBN 0-7897-2239-9

Read my review (more general) for ACCU.

Still Under Construction.

A reader review I had sent to Amazon

I will soon add coding examples.



Jeff Alger: C++ for Real Programmers . Publisher: AP professional. ISBN 0-12-049942-8



First of all I strongly object to the title of the book. The good news about it is that the title for the first edition was even worse, "Secrets of the C++ Masters" . Ch.1 "Why yet another book about C++ ?" is pretentious as it sounds: "... There are 2,768,942 books about C++ and 2,768,940 of them are either for beginners, or about specific compiler, or just about the syntax of C++ ..." .

Well, I'll give the author the benefit of a doubt that for the other two books, he refers (besides his own book) to B. Stroustrup's book.

So what about the books by M. Cline, S. Meyers, M. Henricson & E. Nyquist (to name a few) ? [ more info]

One thing is true, though, there are only a handful of good books about C++, BUT this one, despite some good things in it, is NOT at the top of the list (to put it mildly).

Once you realize that the author is from Microsoft Corporation, things start to clear up: Isn't it the way they always do it, down there at M$ ? [ "Mirror, mirror, tell me who else is ..." ]. P. 52: If the author is so sure he addresses his book to those who already know well the basics of C++, how come he makes two beginners mistakes at a single class ? At class String :

the constructor initializes a pointer to a trivial value ( NULL ), only to start working on it at the body of the constructor. To my view, it is worse than not initializing the pointer at all , since it gives the illusion that it is a well built constructor.

), only to start working on it at the body of the constructor. To my view, it is , since it gives the that it is a well built constructor. How come operator=() is protected against self assignment by a primitive method (which is, I admit, the way I teach my C++ beginner students), and not the better way (see, for example, M. Cline's book C++ Programming FAQs). P. 192: There is a typo (two lines at the top of a function are duplicated). This teaches me one thing, and makes me suspect of another one: Examples were not compiled

Is it the case that the author has been trapped into a bug of (his own company's) M$-Word ? I have no idea which programming language was used for M$-Word and alike, but based on my minimal experience with M$ products, I am quite sure I do not want to learn the way THEY program. Read another (not so friendly) review, from ACCU. It says that the section about smart pointers, and alike, is very good. I trust the reviewer, Francis Glassborow, and he has said it about the 1st edition. Nowadays, there are other good sources for such things, and the reviewer main claim is that the book has not come any better from first edition, and is dated in quite several respects.

Kris Jamsa: Rescued by C++ . Translation to Hebrew: Shmuel Ben-Tolila

Publisher: Hod-Ami.



All over the book it uses void main()

Why NOT void main() P.220, final example before conclusion , class dog has public data . P. 248, class string It uses magic numbers .

. operator+ returns void (and so does operator- ). P. 250, still class string , additive operators return char * , thus allowing unrestricted access to private data. P.269, Ctor for class employee Assignments instead of initializations.

magic numbers .

. No overloading for operator<< . P.270, Assignments in Ctor for class manager . P.272, class book inherits from class library_card . P.375-7, it recommends using MACRO .

Leen Ammeraal: C++ for Programmers 3rd ed. Publisher: Wiley. ISBN 0-471-60697-9

Read my review (more general) for ACCU.

Still Under Construction.

P. 25: "If we use i++ or ++i only to increment i , ignoring the values of these expressions, it does not matter which form is used: ..."

Not quite true : overloading the postfix operator is, usually, done using a temporary, while a temporary is not needed for the prefix version. In some cases the postfix version is a performance burdon. P. 51: Does not teach testing successful input.

An example of while (cin >> i, i > 0) is given

but while (cin >> i && i > 0) is much much much better. P.121(top): int minimum(const int a[], int n)

"Note that the array length is omitted in a[]; if we had written it, then it would necessarily have been a constant, which would have made the function less general and elegant."

Do not believe any word of it. P.145(bottom): "We can write either of the following two line to achieve this:"

int a[2][3] = {{60, 30, 50}, {20, 80, 40}};

int a[2][3] = {60, 30, 50, 20, 80, 40};

but there is no explanation about (the more common situation) where these two styles of array initializations are not equivalent. P.180: Claims that all assignment operators must be overloaded by member functions. This contradicts Stroustrup's 3rd (11.2.2). Indeed, Ammeraal conforms with the literal reading of the C++ Standard, but it seems the wording of the standard is not what the committee intended (and will probably be corrected). P.196: How to get over the possibility of self-assignment? The author prefers the inferior option (see C++ Programming FAQs). P.197: Implements private operator= and copy-Ctor as no-op. P.205 (bottom): " If B is a base class from which D is derived ... a reinterpret_cast is required for the conversion from B* to D*. "

This is a serious mistake.

Almost every non-toy C++ program will crash if the above advice is followed. More to come.

David Collopy: Introduction to C++ Programming - A Modular Approach Publisher: Prentice Hall. ISBN 0-13-888801-9



P.274: Given the definitions (on pages 272, 273) class square{ float a; // The rest of the class }; class rectangle: public square{ float b; // The rest of the class }; It claims that " [ rectangle ] can be written in a way that shows the origin of the definitions: " class rectangle { float square::a; float rectangle::b; // The rest of the class }; Here it uses a depreciating construct (it should have used the using directive).

In this particular case it is obviously wrong, since square::a is private .

In fact, this style is not for " showing the origin of the definitions ", but for the rare cases that someone wants to alter the accessibility level. Regarding data-members, it is (not only) my view that they should always be private , and therefore their accessibility level can never change.





P.274: One of the Notes says:

" If square::show() had been given different parameters than rectangle::show() is given, then they would become practically two different functions, and therefore, rectangle would have two overloaded functions named show() ... " Let's see how many errors are here:

(i) These two function ARE different, as they are now.

(ii) Since rectangle::show() IS OVERRIDING square::show() ,

it seems as if rectangle has a single function show() .

(iii) OVERRIDING a non-virtual function is usually a design error.

(iv) Even if these two functions were declared with different interface,

still rectangle::show() would have been HIDING square::show() .

Therefore, rectangle still have a single function rectangle::show() (as it has now), where the other one is only accessible as square::show() (as it is now).

See what Marshal Cline says about hiding base-class functions: C++FAQ#21.1, C++FAQ#23.3.



P.487: If it deals with the function scanf() (which is not recommended for C++, and is even riskier than its counter-part output function printf() ) - at least it should teach how to use its returned value. In addition, the description of the format-string is so misleading that it should be considered wrong.



More to come.

Enjoy.

A few References:





[K&R2] B. Kernighan & D. Ritchie: The C programming Language , 2nd. ed., 1988, Prentice Hall.





, 2nd. ed., 1988, Prentice Hall. S. Summit: C Programming FAQs , 1996, Addison-Wesley Longman.





, 1996, Addison-Wesley Longman. B. Stroustrup: The C++ Programming Language , 3rd ed., 1997, Addison-Wesley Longman.





, 3rd ed., 1997, Addison-Wesley Longman. S. Lippman & J. Lajoie: C++ Primer , 3rd ed., 1998, Addison-Wesley Longman.





, 3rd ed., 1998, Addison-Wesley Longman. M. Cline & G. Lomow: C++ FAQs , 1995, Addison-Wesley Longman.





, 1995, Addison-Wesley Longman. S. Meyers: Effective C++ , 2nd. ed., 1997, Addison-Wesley Longman.





Go to: