S
spinoza1111
[Seebs - please read this, as I have a question for you at the end.]
*bamf*
"I had been given the mission of creating a complete reference guide to
the C programming language. Not just /any/ book, but the /complete/ book."
*snerk*
Okay, this is from page 420 of the second edition of CTCR, not a page I
recall seeing before.
Well! This is fortuitous.
The 2nd and 3rd edition are extremely similar in page numbering, and while
paging to it, I found my receipt.
I bought the 3rd edition on 1/22/96, specifically to write about it, so I
can now state that the page in question is just over 14 years old. 15 was
an estimate based on the book's copyright date.
It's now page 407, by the way.
This fragment reads up to 128 characters from the file described by fd:unsigned count
char *buf[128];if(_dos_read(fd, buf, 128, &count))
printf("error reading file");
Seebs: was this corrected in CTCR3?
No. But!
The error message was changed to "Error reading file."
So not only are the three obvious errors still there, but they are still
there despite the fact that, demonstrably, someone looked at the example.
I can't find any <dos.h> stuff in the 4th edition; it looks like it was
removed entirely. So, to add insult to injury, not only is it an extremely
buggy example with no explanation offered, but it was NEVER fixed -- at
least some of the errors were "fixed" by making a new edition in which
they are corrected.
Flipped around a bit, found a new example. 4th edition, page 264:
#define MAX_SIZE 100
/* ... */
float balance[MAX_SIZE];
/* ... */
for(i=0; i<MAX_SIZE; i++) printf("%f", balance);
/* ... */
for(i=0; i<MAX_SIZE; i++) x =+ balance;
The reader is encouraged to try to spot errors. I only found two; can
you do better?
(1) You added some special invisible non graphic characters to make
the example not compile with several errors, or those characters were
added by the browser in a way that I have not seen occur before.
(2) It's obvious that i and x need to be defined and that the storage
is assumed to be initialized outside of the example.
(3) As Malcolm has pointed out, code snippets are not standalone and
not meant for incompetent or evil (see below) programmers to type in
uncritically. They are a somewhat harder form of text. They are
exemplary, and "no warranty, etc." You are demanding of Schildt a
level of diligence you did not show in CTCN and you have never shown
here in code examples.
(4) It is in fact common practice to eliminate housekeeping and to
make assumptions when one's a teacher, but neither you nor Richard are
teachers. You are instead evil and incompetent people.
(Note that the last line of the above example wasn't present in the 3rd
edition, where the example appears on page 262, but the other problem
existed then too.)
... And dammit, looking it up, I found another one:
#include <stdio.h>
#define ABS(a) (a)<0 ? -(a) : (a)
void main(void)
{
printf("abs of -1 and 1: %d %d", ABS(-1), ABS(1));
}
When this program is compiled, a in the macro definition will be
substituted with the values -1 and 1. The parentheses that enclose
a ensure proper substitution in all cases.
Never mind the misdeclared main and the missing newline.
**** you, asshole.
Who here can
come up with a case where ABS(x) doesn't produce the expected result?
(Sigh) without looking at your garbage below, we know that Herb, while
he correctly parenthesizes the formal parameters in the macro, failed
to take into consideration what will happen when the macro is used in
a larger expression with an operator of lower precedence than ?:.
Many beginners fail to parenthesize formal parameters and are
surprised when shit happens as a result. They then are admonished to
use parentheses.
Very few C programmers in practice take the next step, although I did
and I taught it at Princeton and Trans-Union. This is to classify all
macros as blocks or expressions, and to always put block macros in
curly brackets and expression macros in round parentheses.
Given your low standard of care in using a switch statement with
fallthrough, I rather doubt in fact that you know or follow either
standard consistently, and given, Peter, your habit of excusing your
own slop with pleas that "it's fast and dirty and I have attention
disorder", I conclude that you are deliberately fucking with Schildt
here out of malice, envy and incompetence.
... Nevermind, it's like shooting fish in a barrel.
printf("abs(3) - 1: %d\n", ABS(3) - 1);
The forth edition points out that the () around a are needed, and illustrates
that, without them, ABS(10-20) wouldn't produce the right results -- meaning
he reviewed this example again and still didn't spot the OBVIOUS BUG.
In terms of actual practice, as opposed to the higher standard I
taught at Princeton and Trans-Union, this is not a bug. This is
because macro code is usually accessible to its user who almost always
is the programmer who wrote the macro, and is designed under time
pressure with a finite and checkable number of uses. Any tool, of
which a macro is an example, has failure points: you don't use a
toothbrush to paint a wall.
In fact, if you happen to inherit some clown's macro library, and it's
in an #included .h file, and you don't have access to the file, and
you want to use what is claimed to be a macro that expands to an
expression, you yourself add the parentheses to make your use of the
tool safe. Likewise if you understand that the macro expands to one or
more C expressions.
If I were a practicing C programmer, I would be loth indeed to use a
macro library from you, but I would use due diligence. I would enclose
what seemed to be expressions in parentheses and what seemed to be
series of C statements in curly braces while holding my nose.
My students at TransUnion were part of Schildt's intended audience.
They were overwhelmed as assembler programmers for IBM mainframes with
the complexity and novelty of C, and did not fully comprehend the need
for so religiously bracketing "expression macros" and "block macros".
This is probably why Herb, as what you in such a self-contradictory
way call a clear writer, does describe the more common practice of
parenthesizing formal parameters and omits, at least here, the more
advanced lesson.
You simply don't exercise enough diligence in your own code, Peter,
for me to think that you do not in fact follow the Nilges rule. You
follow the Peter rule, which is to crank out slop and expect everyone
to applaud. We might, except for your evil and vicious conduct towards
others.
Seriously, guys, this book is MUCH WORSE than I claimed. I thank Mr. Nilges
for making me aware of just how badly I understated the degree to which this
book is utterly unsuitable for teaching C, and if I'd had to review a book
like this, I woulda been quite tempted to argue that it was simply unsuitable
for publication without MASSIVE revisions and corrections.
What a complete, total, and utter fool you are. A combination of
buffoon and evil man which it would take a Shakespeare to fathom.