C Books and C++ Books You Don't Want !

Copyright © 1998-2012 All rights reserved

by Yechiel Kimchi    

Table of Contents
The Age of Disinformation Feb. 10, 2011
Preface
Disclaimer
Notes
Introduction
General
How to choose a Textbook?

Reviews on the Internet
It's not just Books (Oct. 6th, 2012)

Books in English
  1. Schildt: Any Book on C or C++
  2. Pohl: Object-Oriented Programming Using C++
  3. Deitel & Deitel: C++ How to Program
  4. Neibauer: Your First C/C++ Program
  5. Smith: Object-Oriented Software in ANSI C++
  6. Shiflet:Problem Solving in C++
  7. Hennefeld & Burchard: Using C++
  8. Lawlor: Computer Science with C++
  9. SAMS Teach Yourself: C++ in 21 days
  10. SAMS Teach Yourself: C in 21 days
  11. C by Example
  12. Alger: C++ for Real Programmers
  13. Jamsa: Rescued by C++
  14. Ammeraal: C++ for Programmers
  15. Collopy: C++ - A Modular Approach
Books in Hebrew
  1. Kelech: Data Structures implemented in C and in C++ (March 1st, 2006)
  2. Lichtman & Rash: The Complete Guide to the C Language
  3. Nativ: Learning C
  4. Manor: The C Language: Programs and Solutions
  5. Kilstein: The C Language: Exercises and Solutions
  6. Neibauer: Your First C/C++ Program
  7. Jamsa: Rescued by C++
  8. Armon: Introduction to Computer Science with C++
  9. Gerber: C++ as Mother Tongue
References
CopyRight


The Age of Disinformation

This page is continuously

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:

A few tips for choosing a textbook in C or in C++.

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:


Introduction

Bad books on C and C++ (as well as on any other subject) exist in any language that has such books - not just in Hebrew. But I care for the students in Israel, so I comment on books that are available in Israel - mainly in Hebrew and in English (sorry, I do not know Russian, however, several books in Russian that I have seen are translations of books that appear on this list ;-). Indeed, I have not found ANY book in Hebrew (about C or C++), that I thought was good enough to recommend. On the contrary, they are bad enough to cause my students to loose valuable points in their exams - if they use these books to learn these languages.
If you know about a good book in Hebrew, I'll be delighted to hear about it (but if it is not good, it will be added to this list of examples).
The only good thing that I can say about these books is that, overall, they are correct with respect to the syntax of the languages (well, I believe that their examples were correctly compiled ;-), but you will be able to see that even in syntax the books can be improved in one or two things. Regarding syntax, it is my opinion that knowing the syntax of a programming language is just about knowing 5% of what is to be learnt about it.
Some of the bad books in Hebrew, are just translations of bad books in other languages (see below) - it is impossible to introduce conceptual errors while translating.
For obvious reasons, only a small selection of foreign literature (mostly in English) on C and C++ is available in Israeli bookstores. Unfortunately, these books are not always the best choice in their classes (to say it mildly) - and some very good books, on the other hand, are hard to find.
The interested people should either order them personally from a bookstore, or use the Internet in order to purchase them. Books that I recommend are only those that I personally read - though not always cover to cover. My prefered text-books are on a separate page. See a few references at the bottom of this page.


General Remarks about Bad Books
(not necessarily in Hebrew)




My reviews on the Internet



Wrong Information on the Web is also too Common

(Oct. 6th, 2012)

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


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


  1. P. 9, C++ Comments:
    What ???   (*)

  2. P. 11, C++ Comments:
  3. P. 17, What the C Language Can Do for You, and What It Cannot Do:
  4. P. 24, C++ Comments:
  5. P. 27:
  6. P. 251, C++ Comments:


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.

  1. P.59: The Chapter on Classes precedes the Chapter on Functions.
  2. P.64: No initializations in a Ctor.
  3. 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;
          }
        }
    
  4. P.100: Uses #ifdef protection for implementation-file
  5. P.130: Uses exceptions, which are introduced 90 pp. ahead.
  6. P.257: What can be virtual and what cannot:
    On top of redundancy, it forgets static functions.
  7. P.325: A Ctor with two parameters (and no default value(s))
    is declared explicit
  8. P.402:
  9. 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."
  10. 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.

  1. There is hardly inheritance in the book.
  2. 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.
  3. P.810 Using assignment in constructor (rather than initialization).
  4. 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.

  1. There is hardly inheritance in the book.
  2. There is hardly overloading in the book.
  3. P.159 C style for loops.
  4. P.533 void main()
  5. P.533 A List is built, consisting of links only, and without supporting functions.
  6. P.546 A list template is presented, only interface - no implementation.
  7. P.645 Examples of functions:


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

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


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

  1. 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.
  2. P.363 - 365 class String
  3. P.366 In function main()
  4. P.445 The Shape  class hierarchy is a design error  in various aspects.
  5. P.482 class Employee uses getFirstName(), setFirstName()  etc. instead of using function overloading.
  6. 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

  1. I will soon add coding examples (the following are comments on a previous edition).
  2. 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.
  3. The book is full of errors, I'll give you a (short) list of examples in the near future.
  4. (from an older edition) P. 572 - 575 The following two are enough to disqualify a book about C :


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

  1. I will soon add coding examples.


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

  1. 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".
  2. 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 ..."].
  3. 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 ?
  4. 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:
  5. 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.

  1. All over the book it uses void main()
  2. P.220, final example before conclusion, class dog has public data.
  3. P. 248, class string
  4. P. 250, still class string, additive operators return char *, thus allowing unrestricted access to private data.
  5. P.269, Ctor for class employee
  6. P.270, Assignments in Ctor for class manager.
  7. P.272, class book inherits from class library_card.
  8. P.375-7, it recommends using MACRO.
You will be delighted to read a review about another book, by the same author.


Leen Ammeraal: C++ for Programmers 3rd ed. Publisher: Wiley. ISBN 0-471-60697-9
Read my review (more general) for ACCU.
Still Under Construction.

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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).
  6. P.196: How to get over the possibility of self-assignment? The author prefers the inferior option (see C++ Programming FAQs).
  7. P.197: Implements private operator= and copy-Ctor as no-op.
  8. 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.
  9. More to come.


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

  • A tentative review that will appear at ACCU reviews:
    
    	Introduction to C++ Programming - A Modular Approach
    	----------------------------------------------------
    			by David M. Collopy
    
    	[Pub. Prentice Hall, ISBN 0-13-888801-9, @ ? ukp]
    
    
    Reviewed by: Yechiel M. Kimchi
    
    			NOT RECOMMENDED
    			---------------
    
    The subtitle of the book "A Modular Approach" made me think
    it was related to the didactic approach of the author,
    of how to teach C++.  
    I was really waiting for this book to arrive
    - but I was disappointed.  By "modular approach",
    the author means "programming in the module-paradigm".
    Here is how the author uses the module-paradigm in practice:
    
    The last big example in the book (Chapter 15, p. 557)
    is a six-page long program about files updated with
    course-data.  It has global variables for two files,
    a global struct-variable for courses and several
    more global variables.  Then, about ten utility functions
    are all declared to have no arguments and no returned values
    (all are typed as "void f(void)").  As the cherry on the pie,
    main() is in the same file, hence, there is not even
    a minimal attempt to create a genuine, old-style module
    (static variables, as well as multi-file programs are
    unheard of in this book).  Does the program use ANSI-C++ ?
    Not in the least!
    It #includes  <conio.h>,
    main() defaults to int (i.e, no return type
    is mentioned at main() definition),
    and the following statement opens a file (p. 558):
    
    	keyFile.open("a:course.key", ios::out));
    
    Yes, the excessive ')' is there.
    
    The only positive thing that I can say about the book
    is that the author does not hide its shortcomings.
    On the contrary, it actually advertises them (Preface, p. v):
    "This book uses a procedural or non-object-oriented approach
    to learning how to program in C++. ...  
    Topics excluded are object-oriented programming, classes,
    inheritance, unions, functions and operator overloading,
    virtual functions, polymorphism and related items."
    Let me add that the term "template" appears once in the text
    and once in the index,
    but not in the sense you would expect it in a C++ book.
    
    The author claims that the book stresses
    "... programming for business applications." (page iii).
    The following text, taken from page v, explains something
    about the author idea of business programming:
    "Essentially, local variables are used to build applications
    ... for retail sales.  Global variables, on the other hand,
    are often used to construct corporate applications
    that are developed and maintained by in-house programmers."
    I am sure that regular visitors of ACCU reviews
    already know what should be said about global variables.
    However, for the sake of novices let me cite Marshal Cline,
    the author of "C++ FAQs":
    	"Global variables: Just Say No!"
    and, regarding naming conventions,
    	"The names for global data begin with //"
    
    Let me conclude by briefly mentioning that almost
    every program example in the book is preceded
    by flow-charts describing its activities.
    The program example mentioned above is preceded by five pages
    full of thirteen flow-charts.
    It is not that flow-charts are evil, but they are dated
    and used only at the very low-level programming.
    Modern modeling languages like State-Charts or UML,
    together with pseudo-code for low-level activities
    are more appropriate for contemporary programming tasks.
    The excessive use of flow-charts gave me the feeling
    that I was reading a book about programming in Basic
    that was translated to C++.
    
    Not recommended.
    
    


    Books in Hebrew

    Meir Kelech: Data Structures implemented in C and C++ Opus, 2001. (March 1st, 2006)

    1. P.329: Implementation of operator+ for Matrix is over 60 lines long (not including comments). Above all, it returns Matrix*, which is a design error (the fact that the author wants to prevent a copy of a Matrix is not an excuse - he should have sought a different solution).
    2. P.213-215: When implementing a binary-tree in C++, node is implemented as a struct without methods. Leaving aside whether its structure should be public (it should not - think of making it an AVL-tree), not using methods leaves the implementation in a C-style.
    3. P.213 onward: The author uses throw false in variouse places.
      I do not ignore the fact that he never throws true
      but The main thing is that he completely misses the idea of exceptions.
    4. P.217: The function removeRightChild() is implemented so that:
      • It throws an exception (yes, false) in case the child is NULL, which is, at least, questionable.
      • It copies the right child as a temporary subtree, then removes the original, and then
        returns by value a(nother) copy of the removed subtree.
        (not enough space for smilies, sorry)
    5. P.232: The implementation of following function exhibits poor knowledge of programming, even at the level of C.
      class Student
      {
          .....
      
        bool operator== (const student &std) const
        {
          if (id == std.id)
             return true;
          return false;
        } 
          .....
      };
      
    6. P.237: Here is an implementation of binarySearchTree::insert()
      Apart from not compiling this code, you can see that the author does not care about appropriate knowledge of operator new and about exceptions.
      There are more questionable issues here . . .
      void binarySearchTree::insert(node* &root, nodeValue new_value)
      {
        if (root == NULL)
        {
          root = new node(new_value, NULL, NULL);
          if (!root)
             throw false;
        }
        else if (root->value > new_value)
      	insert(root->LChild, new_node);
        else
      	insert(root->RChild, new_node);
      }
      

    Lichtman & Rash: The Complete Guide to the C Language May, 1997.

    1. P.31 (and throughout the book): The book uses void main()

    2. P.48, It refers to float, double, but not to long double. Using float may confuse novices.
    3. P.49, It refers to C data-types on PC only.
      "typedef unsigned int twobytes;" can only mislead.
    4. P.51: Regarding naming of variables it says
      "... in the majority of compilers only 6 to 8 first characters will be recognized ..."
      • K&R2 states that for identifiers with internal linkage at least first 31 characters are significant (and external linkage is not relevant at that point of the book).
        ISO/ANSI-C tends to make the number even higher.

    5. P.53, "b. In case of many global variables ..."
      Instead of recommending to avoid using global variables.
    6. P.57: Regarding the operator % (and operator /), it does not mention what happens in the case of negative operands.
      • K&R2 states (p.41): "The direction of truncation for / and the sign of the result for % are machine-dependent for negative operands, ..."

    7. P.71: "... the prefix incrementing operator, executes the increment first, and then ..."
    8. P.112,
        int r;
        float f, pie;		/* No initializations */
        r = 3;
        pie = 3.1415927;
        /* More digits than are guaranteed for float  */
      
      
    9. P.131: int my_array[10] = {0,0,0,0,0,0,0,0,0,0};
      • The book does not know that partially initialized arrays will be initialized to 0 (See K&R2 4.9 - p.86, A8.7 - p.219).

    10. P.150: There is a #define ROW 5 but 30 is a magic number.
    11. Chapter 7, Designing a Program, gives an example where main() calls do_what('+',a,b) that calls add(a,b) that return a+b; .
      • I wish to meet the student that will understand the deep and very important issues of Top-Down Design and Design for Correctness from that example.
        It is my opinion that this chapter should not have been written at all.

    12. P.185: It says that extern defines variables
      (but it only declares - except when no definition is available).
    13. P.229: Pointers to functions - old style function definition.
    14. P.265: #include <alloc.h>    Not standard (old style).
    15. P.299: (Regarding dynamic memory allocation) it says
      "If we do not test [the value returned from dynamic memory allocation], we will step on other [unexpected] areas [of memory]."
      • This is simply incorrect (since malloc() (etc.) returns NULL on failure).
    16. P.300: "size_t is a Bourland constant" - Mmmm... So simple.
    17. P.327: To my opinion, a poor implementation of Hanoi().


    Y. Nativ: Learning C     2nd ed. Hod-Ami pub.

    1. All over (pp. 191, 193): The book uses void main()
    2. The following two are enough to disqualify a book about C :
      • Using magic numbers  instead of using #define (e.g, pp. 191, 193).
      • Using the library function gets() instead of fgets() (e.g, p. 109).
    3. P. 83: No test for successful scanf()
    4. P. 258: Describing the function fscanf()
      without even a slight reference to its returned value.


    Alon Manor: The C Language: Programs and Solutions Pub: Hod-Ami.

    1. If you use this book as a reference in exam, you will, probably, NOT pass it.


    Daniel Kilstein: The C Language: Exercises and Solutions Pub: ???????.

    1. If you use this book as a reference for an exam, you will, probably, NOT pass it.
      Want to know why? Keep on reading.
    2. Here is question #27 from Ch(7) - pointers:
      Write a program that reads a string of letters and prints, for each letter, as many asterikes (*) as the number of occurences of this letter in the string. E.g,
      A ** (two occurrences)
      B *** (three occurrences)
      C (none)

      Here is how the distinguished () author solves the problem.
      A Hint: If I had given that problem in an exam, and you had solved it as it is done in the book,
      your grade would have become negative.
      Indeed, usually the minimal grade for a problem in my exams is 0 (zero),
      but here I would have made an exception.
      Well, following comments from my colleagues, I admit I have phrased the above too harsh with respect to my students. Indeed, a freshman, first semester students that has just met C, does deserve more than ε of the grade for showing some algorithmic ability. Yet, for an author of a book, that is able to show his ignorance more than anything else - this is inexcusable.


    Alan R. Neibauer: Your First C/C++ Program 1994, see
    This one seems to be the worst C/C++ book ever translated to Hebrew :-(among the ones I have seen ;-)


    Kris Jamsa: Rescued by C++ . ISBN 965-361-110-0 see


    U. Armon: Introduction to Computer Science with C++ Nov. 1996.
    Among the books that were originally written in Hebrew (not translations) that I have read,
    this one is the worst (and Neibauer's is its translated companion).
    (a new edition has the same errors)

    1. P.43 (and throughout the book): The book uses void main(void)

    2. P.49 (and many other places): The book uses global variables in order to transfer arguments into functions !!! (All of them are void f().)
      • What can I say ?
        See what Marshal Cline has to say in C++ FAQ Lite Subject Index G under Global variables: Just Say No!
      • Here is a tip from Cline's book C++ FAQ:
        (Excerpts from FAQ #425 about a naming convention for identifiers)
        • Class names begin with a capital letter.
        • Function names begin with a lower-case letter ...
        • Data member names ... have an underscore suffix.
        • Names for global data (my emphasize, Y.K) begin with //.
        (Yes, your global data should be put in a comment! Y.K.)


    3. P.55: Given char ch = 'A';    what will be printed by the following command:
      cout << ch << ++ch << ch; ?
      The book answers: "Despite the fact that printing will be done from left to right, the order of evaluation [of the ch values] is done from right to left".
      [Therefore the output will be BBA].
    4. P.58: "i += 2    is faster than    i = i + 2".
      • This is true only if you have a retarded compiler ;-)

    5. P.69: It is claimed that "... in the expression b1 || b2 && b3 || b4
      the expression b2 && b3 will be evaluated first."
      • The fact that the above expression will be evaluated as if written
        b1 || (b2 && b3) || b4
        (because && has higher precedence than ||) has nothing to do with order of evaluation. In fact, the subexpression b1 will always be evaluated first because of the sequential nature of operator || (which is related to the short circuit phenomenon).

    6. P.127: "Initializing a two-dimensional array using the { {...}, {...}, ...} idiom is equivalent to initializing it using the {...} idiom".
      • Try to initialize his example of c[][2] both ways, and then use the same two initializations for c[][3], and you will see that they are NOT equivalent.

    7. P.247: "... using global variables is not so desirable, because if there are 100 functions in the file, all of them can modify their values."
      • Too late to tell the reader, after all his examples with global variables !!!
      • Who writes 100 functions in a single file ???

    8. P.267 onward: Showing just the simple C-style structures. No classes, no member functions, no OOP.

    9. P.270: Using global variables struct vector.
      Using File * instead of fstream.

    10. P.300: Uses the C function gets() "... the only one that inputs spaces ..."
      • Forget the C++ input functions ;-)
        What about the C function fgets() that is MUCH safer ???


    Y. Gerber: C++ as Mother Tongue Jan. 1995 (I have not found a later edition).

    1. In many cases main() is defined as implicitly returning int, but in many other cases it is defined explicitly as returning void.

    2. P.11: Wrong definitions for various types (e.g, short is said to always be of size 2 bytes: "2 bytes guaranteed").
      See also P.30 - an int is two bytes.
      • The ONLY things that are guaranteed by the standard (stating informally):
        • A minimum range for type short -
          which is equivalent to having AT LEAST two bytes in size.
        • A minimum range for type long -
          which is equivalent to having AT LEAST four bytes in size.
        • sizeof(short) <= sizeof(int) <= sizeof(long).
        In addition, the intention is that type short will be strictly shorter than type long (see K&R2, p.36).

    3. P.13: It uses float all over the book.
    4. P.28: Operator precedence: Parentheses as punctuation marks (for grouping sub-expressions) - at the top level of the table - are NOT AN OPERATOR.
      The operator :: is missing.

    5. P.30: The C style casting (float)x (which is a depreciating feature in C++, and is always a sign of a poor C++ style) is taught.
      • At least, it should have been taught as float(x), if not as static_cast<float>(x).

    6. P.98-101: A class rect (representing rectangles) is defined and used, as the concluding example of the chapter introducing classes.
      As a C++ problem at an exam, I gave the following question: Find the conceptual errors (not bugs) in the following code example (a Xerox copy of the code was supplemented).
      I will not bother you with the code itself (a better copy), but, are you interested in reading the errors I could find there (there may be more ;-) ? (or copy from here)
      
      			    C++ as a Mother Language
      			    ------------------------
      				By Yitzhak Gerber
      
      
      pp. 98 - 101:   "the final version"
      -----------------------------------
      List of Errors (not ordered by importance):
      
          (0)     No #ifndef protection against multiple inclusion
                   (it may be argued that it's irrelevant here).
          (i)     Make the scaling type a `typedef', for easy modification
                   (too early for `templates', in the book).
          (ii)    Long functions inside class (inline),
                   but short functions - outside
                   (in the book, inlining discussed just before).
          (iii)   Assignments at Ctors [should initialize data members].
          (iv)    "Magic Numbers" in code [should use `enum' values].
          (v)	    Clumsy code at Ctor
      	     [redundant criticism, if avoids code dup].
          (vi)    Code duplication at Ctor and set_a() and set_b()
                   [extract the common parts as independent functions].
          (vii)   Error response is too harsh (exit())
      		[use ILLEGAL values - too early for exceptions].
          (viii)  Error messages go to `cout' and not to `cerr'.
          (ix)    Inspector methods are not `const' [make them `const'].
          (x)	    BAD METHOD NAMING: _a/_b
      	     [instead of length/width/height].
          (xi)    BAD METHOD NAMING: set_/get_
      	     [instead of function overloading].
          (xii)   Horrifying coding style at rect::area(), rect::perimeter().
          (xiii)  rect::show() is bound to `cout' only
      	     [use `ostream' argument].
          (xiv)   Could have used `operator<<'
      	     (though, too early in the book).
          (xv)    main() implicitly returns `int' (a syntax error in C++)
      	     [make it explicit].
          (xvi)   No initializations for `z', `s' at main()
                   [switch declarations order, and initialize].
          (xvii)  Code duplication in main()
                   [exercise all rectangles at a single function].
          (xviii) main() should be on a separate file
      	     [separate from "rect1.cpp"].
          (xix)   File "rect1.h" is not self contained
      	     [#include <stdlib.h> and <iostream.h>].
          (xx)    Horrible indentation.
          (xxi)   #include <process.h>  is non-standard.
          (xxii)  All printings are of '\n', not even a single `endl'.
          (xxiii) Loop variables should be declared inside loops (at show()).
          (xxiv)  Private part is better put at the bottom of the class.
      
      Copyright (c) 1999 - 2003 by Yechiel M. Kimchi
      
      
    7. I planned to add more here (for pp. 100 - 240), but I am fed up with it

    8. P.247: There is a three-page function (yes, 3 pages - 109 lines)
           chess::move(int x, int y) which recursively solves the Knight-Tour problem.
      This is how it can be rewritten in 32 lines:
    9. chess::move(int x, int y)
        {
        static const int
              row_ind[] = {-2, -1, +1, +2, +2, +1, -1, -2},
              col_ind[] = {+1, +2, +2, +1, -1, -2, -2, -1},
              cases     = sizeof(row_ind)/sizeof(row_ind[0]);
      
       	//	....  9 lines 
      
        for (int i = 0; i < cases; ++i) {
          int new_row = x + row_ind[i],
          new_col = y + col_ind[i];
      
        if (check(new_row, new_col))
      {
      board[new_row][new_col] = ++num;
      if (num == 64) return (1);
      if (move(new_row, new_col))
         return(1);
      else
        {
        board[new_row][new_col] = 0;
        num--;
        }
       }
      }
           return (0);
         }
      
      I have left some of the bad style intact (for you to judge).
      Evidently, a book that does not show this simple method for overcoming irregularities in loops cannot teach you C++ as a Mother Tongue !!

      P.250: Here comes the function chess::check(int x, int y)
      that is written as follows:
      chess::check(int x, int y)
       {
        if (x>=8 || x<0 || y>=8 || y<0 || board[x][y]>0)
      return(0);
        else
      return(1);
       }
      


          
      class chess {
        enum {ROWS = 8, COLS = 8, SIZE = ROWS*COLS};
        int board[ROWS][COLS]; // No magic numbers
             //.... the rest of the class ....
      };
      
      
      bool // Boolean type is returned (and not implicit int)
      chess::check(int row, int col)
      {
        return   row < ROWS && row >= 0 // No magic numbers
      	&& col < COLS && col >= 0
      	&& board[row][col] == 0;  // No if, no else
      }
      
      
      bool // Boolean type is returned (and not implicit int)
      chess::move(int row, int col)
      {
        static const int
            row_ind[] = {-2, -1, +1, +2, +2, +1, -1, -2},
            col_ind[] = {+1, +2, +2, +1, -1, -2, -2, -1},
            cases     = sizeof(row_ind)/sizeof(row_ind[0]);
      
      	    //	....  9 lines 
      
        for (int i = 0; i < cases; ++i) {
          const int new_row = row + row_ind[i],
                    new_col = col + col_ind[i];
      
          if (check(new_row, new_col)) { // Improved indentation
            board[new_row][new_col] = ++num;
            if (num == SIZE) return true; // No magic number
            if (move(new_row, new_col)) return true; // No else
            board[new_row][new_col] = 0;
            --num;
          }
        }
        return false;
      }
          
      
    10. 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.

    11. 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.

    12. 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.



    e-mail: mailto.html



    A few References:

    Go to:

      More References
      Choosing a Textbook
      C++ Bad Books
      Yechiel Home Page
      Israel Fights Terror


    This page has been visited [counter] times since 1998/4/12.

    Copyright © 1998-2006 by Yechiel M. Kimchi. All rights reserved.
    http://www.cs.technion.ac.il/users/yechiel/CS/BadBooksC+C++.html
    Created: 1998/4/12       Last updated: 2012/10/0 9:50 IST

    CopyRight Notice:
    Copying this page, or part of its (textual) content, using any kind of medium, form or format,
    is strictly prohibited unless a written permission was given by the author.
    You are allowed to print this page for personal use only.
    You are allowed to create any number of links to this page, or to any part thereof.
    You are kindly asked (but not obliged) to inform me about these links and their (URL) locations.