Preamble:
Here is my review of Chuck Allison's C&C++ Code Capsules . I think it is rather long (and I removed some parts!). I am afraid I need that much to convince people, after your good review. If you feel it should be edited, tell me or do it. As long as it convinces you, it will probably be good enough. Maybe even this long will not convince you, we should then discuss it a bit, it is my point of view, better make it short and let people decide. Maybe I am quite wrong and this should not be published. By the way I did not write about some "core" parts of the book. Some are good but I have reservation about every part, those could take even longer to describe...The Review
Having seen it 'Highly Recommended' on www.accu.org, I expected much from this book. I was expecting a new Effective C++ or Ruminations on C++ that would shed new light on aspects of C++. I hoped the C in the title was not because the book was half C and half C++. I was disappointed on all counts.
This book is about C and C++. You will find chapters devoted strictly to C, some to C++, but most present both the C and C++ aspects of their subject. I am not sure this is useful. Although you may need to know all of C to be a good C++ programmer, many of the C subjects are so simple that you probably already know about them. For example, do you know that
a[i] == *(a+i)? You would learn that in the same chapter that covers pointers to members. I do not see how someone who knows about classes and needs to know about pointers to members would not know that
a[i]is equivalent to
*(a+i).
One of the major problems with this book is its structure. The chapters seem to contain random information given in random order. Suppose you are an adequate C programmer who knows nothing about C++. You already know ANSI C. You find it comforting to read near the start of chapter one that function prototypes are not optional in C++ (page 13). But then on the second half of page 14 you are introduced to the class concept. In exactly a page and a half, you are supposed to understand all this:
-
that a
class
can be defined with thestruct
keyword; - that it can have member functions, including some -constructors- that can initialise the object;
- that C++ lets you define types that allow implicit conversion;
- that calling a function can create a temporary object because of conversion;
-
that
double(1)
uses the C++ function-style cast syntax; - that only one implicit user-defined conversion is allowed in any conversion sequence;
- that there is a standard string class in C++;
- that it can mix with character arrays;
- that it has a '+' operator for concatenation;
-
that "..." is
const char*
in C++.
If that's not enough, one page later (after a program listing), you'll learn about
explicitconstructors... You could not wait!
I think most C programmers would stop right there, and never pick up this book again. If you start with another chapter, you could think "why am I supposed to read about this, before I get to the good stuff". What happens in almost all chapters is that you need to know many things to understand explanations about simpler things.
Now suppose you do not care about its structure. You want to find a subject and read about it. Then the errors, inconsistency, bad style, lack of clarity and precision, etc, will annoy you. I stopped taking notes after a while, but here are a few.
On page 22 he says "the standard C headers are also in the
std namespacein C++ programs, and are prefixed with the letter c." (So: do you have to use
in C++? If you don't, can you write
std::printf?) On page 35 he states re inline, "Certainly a recursive function doesn't qualify for inlining" On page 39 (a typo) "A declaration can appear anywhere a function can"... (I guess it should be "anywhere a statement can").
On page 46, there is a discussion about little-endian vs big-endian (in the middle of a section on pointer arithmetic!). But his example shows all bits in a reverse position.
On page 51, he uses
size_t(it is explained 50 pages later) and mixes it with signed int values.
On page 55, there is a reverse loop to traverse an array with a pointer p:
p= a + n - 1;
while(p>=a)cout<(It would have been better to explain why you should not do this!) On page 108 (and elsewhere), he uses an
assertfor a test that you would certainly need in a working program for run-time validation.On page 149, a
shortis used to store the value of an int value returned by a function.On page 162 (and elsewhere) you'll find code like this:
int result= ...
if (result == 0) result= ...
if (result == 0) result= ...
return result;Looks cute, but is it good style? Wouldn't you put at least the second if in a block with the line result= ...?
On page 229, we learn that "the eight integral types obey the following sequence of inequalities with respect to the maximum value each can represent:
signed charunsigned short signed long Shouldn't that be
<=? (Not an inequality...) And are there not other integral types (bool, char, wchar_t)?On page 253, you will read "To do everything but navigate a class hierarchy or cast away
constorvolatile, usereinterpret_cast". It's probably a simple mistake because the preceding paragraph talks aboutstatic_cast(maybe it should be "To do everything else but..."). By the way, he usually uses old style casts in his programs...On page 278, the word exit is used as a label (for a goto). Is that not very bad style?
In chapter 14 Object-oriented Programming, you will find mostly (27 pages out of 42) MFC code, complete with
BOOL, CString,etc. Do you not find that odd?He seems to really like
gets(). He uses it even in C++ programs and in his chapter (17) on text processing...On many occasions he uses a
while (!feof(f))loop. Sometime there is extra code in the loop that prevents this from being really bad, but not always (for example p.447).Not to mention his repeated use of
using namespace std, even in header files.Finally although the book claims 100% ISO Compliance,
mainis regularly declared without a return type. Some ISO-C++ information seems to have been retro-fitted (there are a couple of#includeleft...). For example, for stream formatting, you will be shown the member functions, likecout.setf(ios::showpoint)(notice it's not ios_base), before the much simpler manipulators (cout<). Finally, far too often, you wonder if the author is missing something. For example, he consistently uses many instructions when outputting many lines:
cout<<...>cout<<...>Instead of
cout<<...><<...>Maybe it is his style, but you are not told you could (should?) do otherwise. And if you think he should use
'\n'instead ofendl, I think you will feel unhappy about code such as:cout<As another example, he shows a custom made manipulator called beep. Not only is this unnecessary (because you could simply output
'\a') but his function outputs char(7) instead of '\a'.To be fair, I stopped reading carefully after about 400 pages. I had received Herb Sutter'sExceptionnal C++and found it much more interesting. But I looked at the last 170 pages: they do not redeem this book. I am sure almost everyone could find something useful in this book, but I am sure everyone will find more uninteresting stuff than necessary...
Do not waste your time and money, there are better books to read.