Archive for Peter Seebach

In the Matter of Herb Schildt: an Analysis of “C: the Complete Nonsense”

Posted in Uncategorized with tags , , , , on April 3, 2010 by spinoza1111

Let’s now deconstruct Peter Seebach’s document “C: the Complete Nonsense”, an attack on Herb Schildt’s first edition of “C: the Complete Reference” which in becoming the sole source of subsequent claims that Schildt wrote “bad books”, which unfairly damaged his good name. Let’s examine it, line by line.

Note that the Amazon link to Schildt is not to the third edition reviewed by Seebach. However, Seebach has failed to update “C: the Complete Nonsense” to reflect fixes to errata, which is itself indicative the malice which makes libel, actionable. He does not even identify the edition he’s analyzing, and at various times, he has changed the online document without any audit trail. He and his friends nonetheless claim that this document is “valuable” consumer information. It is not anything of the sort for this reason alone, and as we’ll see.

Note that the above paragraph was changed when I learned from Seebach on clc that he’s now talking about the third edition, which is out of print. He has a nasty habit of lying online and then laughing as people waste their time and intellect on unsnarling his lies. This habit is one of the characteristics of incompetent programmers.

“C: The Complete Reference is a popular programming book, marred only by the fact that it is largely tripe. Herbert Schildt has a knack for clear, readable text, describing a language subtly but quite definitely different from C.”

In fact, there was more than one C at the time “C: the Complete Reference” and “C: the Complete Nonsense” were written and published (circa 1995), and there remain more than one despite the C99 “standard”. This is because the standard was high jacked by vendors who did not want to change compilers, since this would mean rehiring expensive compiler developers. As a result, the standard left significant parts of C undefined.

For example, because in the “old days” it was easiest for simple “one pass” compilers (compilers which read the source text once) to emit instructions to place the actual parameters of a subroutine call on the stack, you could not expect a(b=0, b) to work like you’d expect it to in a modern language. Other compilers were able to provide the expected left to right evaluation. They were supporting different languages neither with a solid claim to being the lingua franca except to that sort of amateur folk linguist who knows only his own language, and demonstrates for an “English only” society. Seebach seems to be this unpleasant type of person with regards to his favorite languages.

Seebach wanted Schildt to describe the C that Seebach knew.

In addition, Peter Seebach has a knack for unclarity, in his solecism “clear, readable text”. A careful writer would look up the meaning of clarity in the dictionary, and finding that it means contributing to understanding, would qualify “clarity” as “apparent”.

“This page aims to give people a good way to find out what’s wrong with it.”

…as opposed to letting readers figure that out, as if a book were a restaurant. This is what Theodore Adorno calls the “culinary” approach; an only apparently democratic but actually autocratic mode in which the prospective consumer is warned off a book as if the very possibility of critical reading has been erased; in a programming book, trying out code with typos and fixing it.

Furthermore, the document is about the first edition only and has not been updated, which means that it is egregiously poor as any sort of guide to people who want to buy Schildt’s fourth edition; because the market “liked” Schildt, he’s gone to four editions.

“Don’t bother contacting the publisher; they apparently don’t feel these errors are significant.”

We have learned from Seebach himself on comp.lang.c and comp.lang.c.moderated that he contacted McGraw-Hill, and that McGraw Hill actually offered him a temporary tech review job but they failed to offer him enough money for his tastes. And as we shall see, the errors are not that significant.

“The following is a partial list [1] of the errors I am aware of [2], sorted by page number. I am not including everything [3]; just many [4] of them.”

[1] Contradicts “currently known” below. Like Seebach’s solecism in the use of “clear”, which means understandable and providing a clear view of the truth, his slop-English allows him to lie to himself and others. “Currently known” means in the absence of further qualification, “these are all the known errors”.

[2] Implies that there are n errors and the list lists m<n. But what are they? We have no idea.

[3] Why not?

[4] When he says "I am missing several hundred errors", this could mean that Seebach wants people to join in a deliberate campaign to destroy Herbert Schildt's reputation (which is civilly liable, that is, libel) or that he somehow has determined that there are M~=~1000 errors, but he presents N=20. But in this context, N is not "many".

"I am missing several hundred errors [5]. Please write me if you think you know of any I'm missing. [6] Please also write if you believe one of these corrections is inadequate or wrong; I'd love to see it."

[5] This is a very disturbing statement, as above. Did he lose them? Did he forget them? Or did he seek to form a cybernetic mob and gang up on Herb Schildt?

[6] Very disturbing. Peter currently on comp.lang.c has a track record of posting awful code as if he’s seeking assistance. Here, he seems to be Open Sourcing, an Open Season, on Schildt’s reputation.

"Currently known:"

Followed by only 20 errors! So how many are there? Dozens? Hundreds? 20? Nobody knows. But here goes…

Page 19

Schildt: “In general, negative numbers are represented using the two’s complement approach…”

Seebach: “This is not a C feature. It is a common implementation, but it is specifically not required. (Binary is, but one’s complement is not unheard of.)”

Negative numbers are not ALWAYS represented in twos complement notation: but this is what the head of department said in my graduate level class on computer architecture, that in general twos complement is used. This was so students could understand error dumps.

Page 33

Seebach: “The following heading occurs: static Global Variables: no such thing. A static variable outside of a function has file scope, which is distinct from global scope.”

The important distinction in computer science is between variables which are static and have global scope, and variables which are allocated either at procedure startup or in blocks depending on the language, and have local scope.

It is more important to learn this in general for all programming languages so that one can learn new languages. However, Seebach has boasted, in comp.lang.c, that he has not taken a single computer science class, at the undergraduate or graduate level. Herb Schildt has a Master’s in computer science.

p. 53

printf("%f", sizeof f);
printf("%d", sizeof(int));

Seebach: “Clearly wrong; sizeof is not a double or float. It is also not an int; it is an unsigned integral type, thus, one of unsigned char, unsigned short,unsigned int, or unsigned long.”

“The only safe way to do this is: printf(“%lu”, (unsigned long) sizeof(int)); while this is larger, a clear explanation of why it is required will go a long way towards helping people understand C.”

Although I do not know why Herb used %f and %d format codes, he did know, as Seebach seems not to, that all ints are floats and all floats are doubles in well-structured languages. Because at the time and even, to an extent, now, C was almost as diverse of the languages of China, Herb used the educated programmer’s maxim, which is to first code as if the compiler writers and language designers knew at least as much as the intelligent programmer, and fix problems later.

p. 53

“Seebach: The following code:

/* Write 6 integers to a disk file. */
void put_rec(int rec[6], FILE *fp)
int len;

len = fwrite(rec, sizeof rec, 1, fp);
if (len != 1) printf("write error");

is described as causing all of rec to be written, no matter what size of array is being used.”

“Incorrect. As correctly noted elsewhere, when “int rec[6]” is an argument to a function, it actually specifies a pointer-to-int, not an array[6]-of-int. sizeof rec is sizeof(int *) here, and this code works only if sizeof(int *) is precisely 6 times sizeof(int). (Not impossible, but hardly likely.)”

“Further, who said fp was a disk file? fp could be stdout. (An admitted nit.)”

The put_rec code was errata. Peter has said on comp.lang.c that McGraw Hill offered him the chance to work collegially with Herb to fix errata; he refused, he has said, because they didn’t offer enough money. Because Schildt’s books were successful, he’s gone to several editions, and has fixed most of the errata.

Page 59

Schildt: “This shorthand works for all the binary operators.”

Seebach: “No, it doesn’t. It doesn’t work for ‘.’, ‘->’, ‘&&’, or ‘||’. For that matter, it doesn’t work for the function call operator or the array operator, both of which are, roughly, binary operators.

In college lectures which Seebach confesses he did not attend, “binary operators” often is a verbal shorthand for “the commonly known binary arithmetic operators, with logic operators being treated separately”.

The problem here is that adolescents fantasize that there can be unambiguous language, whereas in what Jurgen Habermas, the German “critical theorist” calls “civil discourse”, a common and grown-up search for truth from which competition for gain is excluded, there occurs a constant search among all participants, not only for substantive consensus on a truth, but also for support for that common consensus in the form of a common language, whose micro-rules vary in a language game…what Wittgenstein said was a form of life, as well.

Put more simply, for the same reason we can use a noun as a verb in “let me email you the email” and be understood perfectly, the human brain, as opposed to a computer, has an unparalleled ability to parse and reparse holistically and rapidly, while searching, not for the most advantageous parse to the owner of the brain, but for the best fit.

Therefore, in a college classroom, a teacher like Herb, who has just introduced the arithmetical binary operators, and who plans to address logical and other binary operators later, is understood by normal, and attentive students.

However, Peter Seebach has said on comp.lang.c that he is “attention disordered”. This would give him rights of charity save for the fact that he on that forum has called people he doesn’t like “morons” and “insane”, using a language which even Sarah Palin, of all people, correctly recognizes as discriminatory and abusive.

Here, Peter, for personal advantage (in fact, I believe, to dishonestly establish himself to be a clever programmer despite his lack of academic background in computer science or any evidence of programming competence in code swatches he has posted this year on comp.lang.c) interrupts the flow of civil discourse in a virtual classroom and is the bane, in fact of computer instructors: the student with a chip on his shoulder who wants to show off his “knowledge”.

Page 63

Seebach: “If scanf fails, the variable guess is referenced before it has been initialized; accessing an uninitialized object introduces undefined behavior.”

Errata. Seebach was invited to work collegially on the sort of errata which creeps into computer books when the publishers don’t allow the authors post-PDF control, and he refused. Most of these errors were fixed in subsequent editions.

Page 131

Schildt: “Memory allocated by C’s dynamic allocation functions is obtained from the heap — the region of free memory that lies between your program and its permanent storage area and the stack.”

Seebach: “C does not specify that there is a stack – only that functions can call each other. The “heap” is a DOS term, and the layout is not a part of the C language. It is not atypical for the layout to be radically different, and certainly, there is no call for describing a specific choice as ‘what happens’.”

Seebach lays an egg. Like a like a Maoist student during the Cultural Revolution, he leaps up to admonish the teacher not to talk about stacks as if it’s even possible to implement C’s runtime, or any language runtime, without stacks.

He then surpasses this, and says “the ‘heap’ is a DOS term”. The “heap” is most definitely not a DOS term: Seebach is ignorant of OO languages which formalize a heap…and a stack. Here is where Seebach’s lack of education is most obvious.

It is formally impossible, in fact, to implement a runtime with support for recursive procedures (supported by all C compilers and runtimes since day one) without a stack, that is, a LIFO data structure. It is painfully possible to go without a stack, and save and return general registers in work areas provided by the caller; this was done on the IBM 360 in BAL in my direct experience. But it does not work if a procedure calls itself directly or indirectly. Some sort of LIFO stack, implemented in an unspecified way, is needed.

The only reason why the C99 standard document fails to use the word “stack” that I can imagine is a long-standing American prejudice against the stack, which surfaced both in the design of the IBM/360 (whose designers knew about stacks, probably, but used general registers instead) and much later in the RISC kiddie’s hatred of stacks.

Page 132

Schildt: “After the assignment, p points to the first 1000 bytes of free memory.”

Seebach: “No, p points to at least 1000 bytes of allocated space, which is not free memory. There is also no reason to assume it was the ‘first’ 1000 bytes; top-down allocation is not atypical, and further, there’s no reason to assume this code fragment runs in isolation.”

Schildt like most good writers, tries to be conversational in presenting difficult material. “Free” was a minor solecism.

But, far more perniciously, Seebach actually equates negative claims with positive claims and often prefers, whether writing about Schildt or C standards, the negative claim as being not only true, but also easier to defend because harder to disprove by men of good will.

Seebach has blogged in public, circa 2000, his preference for George Bush. He, like most former Bush supporters, has disclaimed further support. Nonetheless, his support for Bush is interesting, because for Bush’s henchman Karl Rove (a college dropout who like Seebach considers himself a genius autodidact), it was only necessary to claim that Saddam Hussein, in 2003, had weapons of mass destruction, and let the (huge) antiwar movement try to “prove a negative”.

Therefore here and elsewhere, Seebach would “teach” C in a faux-Zen way, beating students who conclude from the behavior of anyone compiler and runtime that “C” works “this” way. To him, their knowledge is Sophistry, but as an “expert” his is the larger Sophistry. This is his false belief that C has been “standardized” by negative truths to wit that various behaviors (order of evaluation of actual parameters, when pre and post increment operators are evaluated) when a language standard must actually be useful and therefore, deterministic.

Schildt is like a competent high school geometry teacher who uses a specific triangle with a specific metric to demonstrate the Pythagorean theorem. Seebach, who isn’t paying attention and may be autistic, is interrupting the class to ask whether the nonzero width of the chalk marks should be accounted for.

This would be an intelligent question…in an “advanced” class. But in computer science, there are no “advanced” classes in being a language lawyer, since (1) being a language lawyer doesn’t help much in problem solving for the most part and (2) Seebach is in a language where, even after standardization and in the standard itself, the “law” is “unspecified” in too many places.

Page 162

Seebach: “Functions are not of type void; functions are of various types, called collectively the function types. A function may have a return of type void, which means that its type is something like ‘function taking (…) and returning void’.”

Mr. Snoid is lost in the void. Herb knows very well that to return “void” is to return nothing and not return anything. Syntactically, in a way the student needs to know, the type of a void function is “void”.

Both Seebach and Schildt are using reifying language, treating our ideas about what electrons do in a computer as things. Peter would renarrate the void function as returning something named “void”, which does not exist, and Schildt’s language is better, since void functions are something of a special [syntactical] type, which is not returned.

Page 163

Schildt: “You may also declare main() as void if it does not return a value.”

Seebach: “Specifically untrue. ANSI mandates two declarations for main, and says that main may have declarations compatible with those. Both return int.”

C was not standardized at the time this book was written, it existed in several different dialects. In fact, I discovered (on behalf, as it happens, of John “A Beautiful Mind” Nash) that the Microsoft compiler, which many of Schildt’s readers were using, is nonstandard at least as regards the evaluation of compile-time constant expressions. While it has become a Shibboleth or Secret Handshake among non-Microsoft Illuminati that you must declare main as int, it’s actually better style to make it void unless you have an important message, such as “up yours!” to the OS.

But this shibboleth has become an article of faith amongst the anti-Microsoft crowd who compensate for the meaninglessness of their lives and general incompetence by fantasizing that they are Special, and the OS gives a hoot.

Page 197

Seebach: “It is redundant to give a size of char in bytes as 1 as an “assumption” – it’s the definition, sizeof() gives the size in *chars*.”

Shibboleth. And here, Peter Seebach is here critiquing writing as a technical editor when he gave evidence in the prologue above that he can’t write with charity, clarity (the clarity of truth), coherence or consistency.

Page 247

Seebach: “The stream fp is opened with mode “r”, the mode to open a text file. Then, fseek is called on fp, with the 2nd argument not a value returned by a previous call to ftell.”

“ANSI For a text stream, either offset shall be zero, or offset shall be a value returned by an earlier call to the ftell function on the same stream and whence shall be SEEK_SET.”

“In other words, this is blatantly invalid.”

Genuine errata of the sort to be expected under deadline pressure. Pompous and exhibitionist quotation from a standard doesn’t change this.

Page 253

Schildt: “In most implementations, the operation fails if the file specified in the open statement does not exist on the disk.”

Seebach: “To the best of my knowledge, POSIX (the standard for the open() call) documents and requires the functionality of the O_CREAT flag.”

But, the operation fails if the file does not exist on the disk. Seebach’s point is “I’m real smart”.

Page 283

Schildt’s code:

#include string.h // corner chars deleted to format

char s1[] = "hello ";
char s2[] = "there.";

void main(void)
int p;
p = strcat(s1, s2);

Seebach: “It is correctly noted that this generates a warning. Not mentioned is that it’s invalid; although s1[] is a modifiable array, it is an array large enough to hold “hello ” (and the terminating null byte), so it has room for 7 bytes. The strcat overflows the array, producing undefined behavior.”

“(And, of course, the declaration of main is invalid.)”

Genuine errata. Seebach is not doing so good. Only 2/14 at this point.

Page 284

Seebach: “All of the header files are listed in capitals; the standard specifies them in lower case. It is not required that a C compiler reject all-caps, but nor is it required that it accept them.”

“But nor is it required”? A completely illiterate grammatical solecism. How dare does Seebach pretend to be a tech editor? He was offered a job finding errors. He found a few.

And furthermore, C should reject all-caps: it would do so if it were a truly consistent language. But it as a real language in practice it allows them because of Microsoft’s market power.

Page 314

Schildt: “However, since EOF is a valid integer value, you must use feof() to check for end-of-file when working with binary files.”

Seebach: “Not merely a little bit untrue, but utterly wrong, and specifically missing the point of the rule (correctly stated) about returning the char as ‘unsigned char converted to int’ (actually stated in the standard in, under fgetc()).”

“Since EOF is a negative integral constant, it can never compare equal to any unsigned char. When you are reading from a binary file, the values you get willnever compare equal to EOF, until getchar() returns EOF because the file is empty.”

“This correlates with a mistake made in all of the examples where loops break on ‘$’, ‘A’, or ‘ ‘ because the return from getchar() is immediately put into a char variable.”
“This is a more serious flaw than many, because it results in poorly written, inefficient code.”

“(Couple this with the consistent attempts to use feof() to see if the next read will fail, when in fact feof() only returns true when the previous read failed, and you get a completely wrong description of the standard I/O library.)”

“Also, several of the programs given loop forever if an end of file is reached, because EOF is not checked for in a loop.”

“(The astute reader will note that he is correct for implementations in which char and int are the same size; I disregard this because: This violates the spirit, if not the letter, of the standard. The implementation he is discussing does not have this problem.”

“In such an environment, the “correct” thing to do is probably to use fread and check for failure. feof() will still not warn you that your next read will fail.)”

Probably Herb’s most serious error, but of the sort which creeps into most computer books, including Seebach’s Apress title as he admits. Software books disclaim warranty protection for the consumer in the same way software warranties make this disclaimer.

Page 333

Seebach: “After

char str[80];

sprintf(str,"%s %d %c", "one", 2, 3);

it is asserted that str will contain ‘one 2 3’. This is incorrect; it would contain “one 2 ^C”. (That’s ‘control C’ in ASCII, or a character with the value 3)”

Errata. And grandstanding.

Page 348

Schildt: “This program checks each character read from stdin and reports all uppercase letters:”.

Seebach: “He is wrong.”

#include ctype.h // corner chars deleted to format
#include stdio.h

void main(void)
char ch;

for (;;) {
ch = getchar();
if(ch == ' ') break;
if(isupper(ch)) printf("%c is uppercase\n", ch);

“The code works only if there are no uppercase letters following the first space in the standard input stream; further, a file consisting only of the word ‘hello’ will prevent this horribly broken code from terminating – because it doesn’t check for EOF, only for a space.”

“Once again, even a slight clue about EOF would help a lot here.”

Errata. Most of Seebach’s points about EOF handling are valid, but what’s broken is the way C, whether “standardized” or not, handles EOF.

Constant is the tendency to make an inferential leap from error to ignorance, and from special to general ignorance. It is adolescent.

Page 434

Schildt: “free() must only be called with a pointer that was previously allocated with one of the dynamic allocation system’s functions (either malloc(), realloc(), or calloc()).”

Seebach: “Also specifically untrue. ANSI states that free(NULL) is valid and has no effect. (Also note that it must be called with a pointer to space previously allocated, not with a pointer previously allocated, and that the pointer must not have been already freed or passed to realloc().)”

There is no sensible use for free(NULL) save in code generation with the preprocessor or other tool: this fact is obscure and shouldn’t be presented at this point. The latter part of Seebach’s comment is again a Maoist attempt to prove that he’s smarter than the teacher. Herb is giving advice that is practical and true which if followed, works.

Page 735

Seebach: “This is spectacularly wrong; the ‘corrected’ “

x = *p * (*p++);

“is EXACTLY equivalent in terms of C; as correctly noted earlier, the order of evaluation IS NOT SPECIFIED.”

“The code is still invalid (p is used to determine *p on the left of the *, as well as modified on the right), and the parentheses aren’t affecting the code at all.”

“In this code, p can be incremented anywhere in the line; the only requirement would be that the value of (*p++) be the same as the value of (*p) before the increment. It is not specified whether the other *p happens before or after the increment.”

“In fact, because the code modifies an object (p) and uses the value of the object to do something other than determine the new value (The first “*p”), it is invalid. Completely; a compiler is allowed to reject the code, and many will produce surprising results from this operation.”

“This is not merely wrong, it’s wrong while discussing the problem, which is doubly bad.”

The order of evaluation is indeed specified in the variant behavior of C compilers, whose writers, as mere programmers, were given no guidance by the standard.

This was because C standardization occured after the “Reagan Revolution” empowered private companies and computer thugs to use the public good for private gain. In the C99 standard, Job One seems to have been not making vendors rehire compiler developers so that their stock price was maintained. The standard is useless to mere programmers, who are considered serfs today.

At this point in “C: the Complete Nonsense”, Peter Seebach has identified only 5 errata, of the sort that exist in all books unless the publisher allows the authors to use a system to avoid errata. And yet he writes at the end:

“There are dozens of others, and I’m sure there’s an effective drinking game lurking in this book.”

In other words, Seebach Open Sources here an Open Season on Schildt based on his malice. This is civilly actionable libel.

Seebach needs to remove this document, which is “hit” by Google higher than Schildt’s book’s fourth edition, which dishonestly misdescribes the current edition, and which is the source, as far as I can determine, of all subsequent attacks on Schildt’s output. He needs to replace it by an apology to Herb.

Seebach appears to me stuck at the level of the vicious adolescent. In “You Are Not A Gadget”, Jaron Lanier (a musician, computer scientist, and philosopher) writes that what he calls “drive-by anonymity”, the marshalling of an assault on a Chosen target by anonymous posters can indeed scale up, from the personal anguish caused Herb and his family when his name was transformed, based exclusively on “C: the Complete Nonsense” to “Bullschildt”, to the death threats received by Java author Kathy Sierra, to the “tea party” attacks on Obama…and beyond.

But, you may say, Seebach is not anonymous. Lanier, in fact, misses the social structure of enabling. In the case of Sierra, named, non-anonymous bloggers at the defunct site started in on Sierra. This enabled anonymous bloggers in the same way anonymous commenters say the most broad and overgeneralized things about all of Schildt’s books, based on “C: the Complete Nonsense” and documents which cite CTCN directly or indirectly, the “paper trail” seeming to ignorant people a vast amount of real evidence.

Hitler was not anonymous; but his followers were, in many cases. And Mike Godwin is wrong; the probability of comparision to Hitler in online discussions “converges to unity” not because people are being shrill and foolish, but because Hitler is our inner troll, as Lanier calls it. He’s the face in the crowd in Munich in August 1914 baying for war who yearns to be on the podium, and non-anonymous.

Actually I should have been able to deduce Fascism from the memory of my childhood. It sent its emissaries there in advance, like a conqueror into the most distant province, long before it arrived: my school comrades. If the bourgeois class harbored since time immemorial the dream of the wild popular community, the oppression of all by all, then children with first names like Horst and Jürgen and last names like Bergenroth, Bojunga and Eckhardt, theatrically staged the dream, before the adults were historically ripe enough to realize it. I felt the violence of the image of horror they were striving for so clearly, that all happiness afterwards seemed to be revocable and borrowed. The outbreak of the Third Reich did indeed surprise my political judgment, yet not my fearful premonitions. So closely had all the motifs of the permanent catastrophe brushed against me, so inextinguishably were the warning signs of the German awakening burned into me, that I recognized each one all over again in the features of the Hitler dictatorship: and often it appeared to my foolish horror, as if the total state had been invented solely against me, in order to inflict on me what I had been hitherto spared in my childhood, that state’s prehistory. The five patriots who attacked a single schoolmate, beat him up and, when he complained to the teacher, defamed him as a classroom snitch – aren’t they the same ones, who tortured prisoners, in order to prove the foreigners wrong, who said that torture was occurring? Whose hullaboo knew no end, when the smartest student made a mistake – didn’t they surround the Jewish camp prisoner, grinning and embarrassed, making fun of him, after he all too clumsily sought to hang himself? Who couldn’t write a single decent sentence, but found every one of mine too long – didn’t they abolish German literature and replace it through their scribing [Schrifttum]? Many covered their chests with mysterious insignia and wanted to become naval officers in a landlocked country: they declared themselves leaders of storm troopers and detachments, the legitimizers of illegitimation. The involuted intelligent ones, who had as little success in class as the gifted tinkerer without connections under liberalism; who for that reason curried favor with their parents with woodsaw work, or indeed drew for their own pleasure on drawing-boards with colored inks during long afternoon days, helped the Third Reich to its cruel efficiency and are being betrayed once again. Those however who always defiantly stirred up trouble against the teacher and, as one called it, disturbed the lesson, the day – indeed, the hour – they graduated from high school, they sat down with the same teachers at the same table with the same beer, as a confederation of men, who were born followers, rebels, whose impatient blows of the fist on the table already drummed the worship of the masters. They need only stay put, to catch up with those who were promoted to the next class, and revenge themselves on them. Since they, officials and candidates for death sentences, have stepped visibly out of my dreams and have expropriated my past life and my language, I don’t need to dream of them any longer. In Fascism, the nightmare of childhood has realized itself.

Theodore Wiesengrund Adorno, Minima Moralia, 1948


An exemplary string replacement function in C

Posted in Uncategorized with tags , , , , , , on February 9, 2010 by spinoza1111

I don’t much like the C programming language, but as part of my Internet anti-bullying campaign (including the campaign against the anti-Schildt swift-boating campaign mentioned elsewhere here in my blog), I am relearning it in order to make my points more effectively at the usenet/Google Group comp.lang.c.

This is where the instigator of the anti-Schildt swift boating (Peter Seebach) resides. He’d posted a piece of code purporting to replace %s by strings, but I noticed that in using the C library string.H, he’d been blinded by the poor implementation of strings in C.

He’d used a character find to locate the percent sign in two different places, and hadn’t bothered, by his own admission, to check for the following s. This meant that correcting the code involved making the same clumsy change in two separate places, guaranteeing further problems.

I discussed a real string replacement program, but actually thinking about “strings” independent of “character arrays with a Nul at the right” is beyond the day to day ken of many C programmers due to the subtle ways in which string.H blinds the soul.

I then demonstrated a straightforward replace() function, working collaboratively online with a few well-intentioned posters who were willing to find bugs.

In Swift Boat mode, Seebach of course interpreted this as “posting buggy software”. Since I don’t take shit, the fun was on at the link below.

It amused me to get back up to speed in C after many years (having helped John “A Beautiful Mind” Nash with C at Princeton in 1991) in order to prove my point: that today’s corporate programmers rarely program, are unqualified, and tend to be bullies, who see in others “the secret contour” of their own weakness, incompetence and fear.

See this link for the Google Group discussions. Warning: drink deep or drink not from this Pieran spring, for the discussion is a real free for all, and it is a big mistake to make conclusions after reading only a few posts. Indeed, the Thugs rely on superficial readings absent any sort of moral grammar, so that their favorite argument, the criminal’s tu quoque, can be used.

Here is the code of a replace() function. It is raising for me some interesting questions of theory and method which I shall pursue primarily in the thread from hell with updates here. In particular, C is strongly biased towards Western languages read left to right, and the VERY interesting problem of a string like “banana” and a replacement of ana by omo (bomona or banono?) needs to be addressed.

Even more interesting would be the relationship of the straightforward-if-crude algorithm used below and the Boyer Moore algorithm.

Also, an argument, germane to some possible real-world applications, could be made that “banana” contains TWO partly overlapping occurences of ana, and could be converted to bonono! Boyer Moore may anticipate this: I need to recheck this source.

But: the Google Groups discussion is why I’m delighted to be a teacher today. My father asked me what would happen when all the code was written. The answer seems to me to be that a eunuch priesthood of machine tenders, without qualifications, courage, spirit, or heart, would then tear at each other for sinecures maintained only because someone needs to hold down the null function in the corporation.

Here is the code.

// *************************************************************** 
// *                                                             * 
// * replace() demo                                              * 
// *                                                             * 
// * Demonstrates how to replace non-NUL-defined strings in C    * 
// * using a simple function, and bypassing string.h.            * 
// *                                                             * 
// * C H A N G E   R E C O R D --------------------------------- * 
// *   DATE     PROGRAMMER     DESCRIPTION OF CHANGE             * 
// * --------   ----------     --------------------------------- * 
// * 02 07 10   Nilges         Version 1.0                       * 
// *                                                             * 
// * 02 07 10   Nilges         Bug: partial matches not handled  * 
// *                           correctly: need to iterate search * 
// *                           for match.                        * 
// *                                                             * 
// * 02 07 10   Nilges         1.  Santosh suggested tests       * 
// *                           2.  Heathfield put the boot in re * 
// *                               including malloc              * 
// *                                                             * 
// * 02 07 10   Nilges         1.  Remove string.h use and code  * 
// *                               strlen by hand                * 
// *                           2.  Add comment block and comments* 
// *                               inline.                       * 
// *                           3.  free() storage                * 
// *                           4.  Use macro for testing         * 
// *                           5.  Bug: calculation of           * 
// *                               lngNewLength used incorrect   * 
// *                               index (intIndex3 instead of 2)* 
// *                               which caused a memory leak.   * 
// *                                                             * 
// * 02 07 10   Nilges         1.  Bug: Ike Naar test failed.    * 
// *                               At end of scan loop, main     * 
// *                               string pointer was not        * 
// *                               correctly updated from index3 * 
// *                                                             * 
// * 02 07 10   Nilges         Added new Santosh test            * 
// *                                                             * 
// * 02 07 10   Nilges         Added new Ike Naar test           * 
// *                                                             * 
// * 02 08 10   Nilges         1.  Added some new comments       * 
// *                           2.  Make "check for a complete    * 
// *                               match "structured" by means   * 
// *                               of a tested assignment        * 
// *                           3.  Get rid of "replace at end"   * 
// *                               evilness: the only time this  * 
// *                               flag is meaningful is in the  * 
// *                               LAST segment.                 * 
// *                           4.  Return replace count          * 
// *                           5.  TESTER macro assertion added  * 
// *                                                             * 
// * 02 10 10   Nilges         1.  Bug fix: in a partial match,  * 
// *                               the main scan index is set to * 
// *                               one past the end, which misses* 
// *                               full matches that start       * 
// *                               between the first character of* 
// *                               the partial match and its end.* 
// *                                                             * 
// *                               No longer updating the main   * 
// *                               scan index (ptrIndex1) to the * 
// *                               point of partial match        * 
// *                               failure: setting it one past  * 
// *                               the first character of the    * 
// *                               partial match.                * 
// *                                                             * 
// *                           2.  Line up expected & actual     * 
// *                               results per excellent         * 
// *                               suggestion (who made this?)   * 
// *                                                             * 
// *                           3.  After a partial match, update * 
// *                               the main handle search index  * 
// *                               (ptrIndex1) to the first      * 
// *                               occurrence of the handle      * 
// *                               character after the start of  * 
// *                               the partial match, or to the  * 
// *                               index of the unmatched char.  * 
// *                                                             * 
// * 021310     Nilges         Bug: failed to handle a one-char  * 
// *                           replace (of a by x in b) since    * 
// *                           we set ptrIndex2 to point to NUL  * 
// *                           which made it appear that there   * 
// *                           was a match. When the main index  * 
// *                           to the master string (ptrIndex1)  * 
// *                           goes off the end of a cliff, we   * 
// *                           needed to break out of the search * 
// *                           loop.                             * 
// *                                                             * 
// *                           This also entailed setting the    * 
// *                           target index ptrIndex2 to 0 at the* 
// *                           beginning of each search so that  * 
// *                           it is not erroneously used to     * 
// *                           indicate that there's an insert   * 
// *                           needed at the end.                * 
// *                                                             * 
// *                           I have also added additional tests* 
// *                           to verify that the code works     * 
// *                           when the string and target end    * 
// *                           at the same time.                 * 
// * ----------------------------------------------------------- * 
// *                                                             * 
// * "In the near future we shall have to live with the          * 
// *  superstition that programming is 'so easy that even a      * 
// *  Republican can do it!'"                                    * 
// *                                                             * 
// *                   - E. W. Dijkstra                          * 
// *                                                             * 
// *                                                             * 
// *************************************************************** 
#include <stdio.h> 
#include <stdlib.h> 
// ***** Segmentation ***** 
struct TYPsegmentstruct 
       { char * strSegment; 
         long lngSegmentLength; 
         struct TYPsegmentstruct * ptrNext; }; 
// --------------------------------------------------------------- 
// Calculate string length 
long strLength(char *strInstring) 
    char *ptrInstring; 
    for (ptrInstring = strInstring; *ptrInstring; ptrInstring++); 
    return ptrInstring - strInstring; 

// --------------------------------------------------------------- 
// Replace target by replacement string in master string 
// Caution: the string returned by this function should be freed. 
char * replace(char * strMaster, 
               char * strTarget, 
               char * strReplacement, 
               long * ptrReplacements) 
    char * ptrIndex0; 
    char * ptrIndex1; 
    char * ptrIndex2; 
    char * ptrIndex3; 
    char * ptrIndex4; 
    char * strNew; 
    char * strNewStart; 
    long lngNewLength; 
    long lngCount; 
    long lngReplacementLength; 
    struct TYPsegmentstruct * ptrSegmentStructStarts; 
    struct TYPsegmentstruct * ptrSegmentStruct; 
    struct TYPsegmentstruct * ptrSegmentStructPrev; 
    lngReplacementLength = strLength(strReplacement); 
    if (!*strTarget) 
        printf("Error in calling replace(): target can't be null"); 
    ptrIndex1 = strMaster; 
    ptrSegmentStructPrev = 0; 
    lngNewLength = 0; 
    *ptrReplacements = 0; 
        ptrIndex0 = ptrIndex1; 
        ptrIndex2 = 0; 
        while (-1) 
            // --- Check for (one character) handle 
                *ptrIndex1 && *ptrIndex1 != *strTarget; 
            if (!*ptrIndex1) break; 
            // --- Check for complete match while remembering the 
            // --- last position of the handle 
            ptrIndex4 = 0; 
            for(ptrIndex2 = strTarget + 1, 
                ptrIndex3 = ptrIndex1 + 1; 
                *ptrIndex3 == *ptrIndex2; 
                ptrIndex3++, ptrIndex2++) 
                    if (*ptrIndex3 == *strTarget 
                        ptrIndex4 == 0) ptrIndex4 = ptrIndex3; 
            // End test: check complete match, update main ptr past 
            // partial match while checking for end of loop 
            if ((!*ptrIndex2 ? ((*ptrReplacements)++, -1) : 0) 
                (!*ptrIndex3 ? (ptrIndex1 = ptrIndex3, -1) : 0)) 
            // Update the main search pointer 
            ptrIndex1 = (ptrIndex4 == 0 ? ptrIndex3 : ptrIndex4); 
        // --- Create new segment 
        if (!(ptrSegmentStruct = 
              malloc(sizeof(struct TYPsegmentstruct)))) 
        ptrSegmentStruct->strSegment = ptrIndex0; 
        ptrSegmentStruct->lngSegmentLength = 
            ptrIndex1 - ptrIndex0; 
        ptrSegmentStruct->ptrNext = 0; 
        if (ptrSegmentStructPrev != 0) 
            ptrSegmentStructPrev->ptrNext = ptrSegmentStruct; 
            ptrSegmentStructStarts = ptrSegmentStruct; 
        ptrSegmentStructPrev = ptrSegmentStruct; 
        // --- Update mallocation length 
        lngNewLength += ptrSegmentStruct->lngSegmentLength + 
                        (ptrIndex2 && !*ptrIndex2 
        // --- Get past end of target string & iterate 
        if (*ptrIndex1) ptrIndex1 = ptrIndex3; 
    // --- Allocate just enough storage for the new string 
    if (!(strNewStart = malloc(lngNewLength + 1))) abort(); 
    // --- Build the new string whilst freeing the list 
    strNew = strNewStart; 
    ptrSegmentStruct = ptrSegmentStructStarts; 
    while (ptrSegmentStruct) 
        for (ptrIndex1 = ptrSegmentStruct->strSegment, 
             lngCount = 0; 
             lngCount < ptrSegmentStruct->lngSegmentLength; 
             ptrIndex1++, lngCount++, strNew++) 
             *strNew = *ptrIndex1; 
        if (ptrSegmentStruct->ptrNext 
            ptrIndex2 != 0 && !*ptrIndex2) 
            for (ptrIndex1 = strReplacement; 
                 ptrIndex1++, ++strNew) 
                 *strNew = *ptrIndex1; 
        ptrSegmentStructPrev = ptrSegmentStruct; 
        ptrSegmentStruct = ptrSegmentStruct->ptrNext; 
    *strNew = '\0'; 
    return strNewStart; 

// --------------------------------------------------------------- 
// Statement-format test macro 
#define TESTER(resultPtr, master, target, replacement, expected, 
expectedReplacements, replacements) \ 
{ \ 
    printf("Replace \"%s\" by \"%s\" in \"%s\"\n", \ 
           (target), (replacement), (master)); \ 
    printf("Expect \"%s\":\n       \"%s\"\n", \ 
           (expected), \ 
           resultPtr = replace((master), \ 
                               (target), \ 
                               (replacement), \ 
                               &(replacements))); \ 
    printf("Replacements expected: %d: replacements: %d\n", \ 
           (expectedReplacements), \ 
           (replacements)); \ 
    if (!(strLength(resultPtr) \ 
        == \ 
        strLength(master) \ 
        + \ 
        (strLength(replacement)-strLength(target)) \ 
        * \ 
        replacements)) \ 
        printf("Assertion failed\n"); \ 
    printf("\n\n"); \ 
    free(resultPtr); \ 

// --------------------------------------------------------------- 
// Main procedure 
int main() 
    char *ptrResult; 
    long lngReplacements; 
           "a stupid error", 
           "stupid error", 
           "a miracle", 
           "a stupid error", 
           "a miracle error", 
           "the stupid error", 
           "the stupid error", 
            "a miracle", 
           "a miracle", 
           "the miracle", 
           "a miracle", 
           "a miraclsnirpKamunkle", 
           "a miracle", 
           "a miraclesnirpKamunkle", 
           "a miracle", 
           " a miraclesnirpKamunkle", 
           "a miracle", 
           " snirpKamunkle", 
           " a miraclesnirpKamunklea miraclea miracle", 
           "a miracle", 
           " snirpKamunkle", 
           "a miracle a miraclesnirpKamunkle a Miraclea miraclea 
           "a miracle", 
           " snirpKamunkle a Miracle", 
           "a stupid errord", 
           "stupid error", 
           "a miracled", 
           "a stupid errod", 
           "stupid error", 
           "a stupid errod", 
           "a sstupid error", 
           "stupid error", 
           "a smiracle", 
           "a stupid errorstupid error", 
           "stupid error", 
           "a miraclemiracle", 
           "a stupid error stupiderror", 
           "stupid error", 
           "a miracle stupiderror", 
           "In the halls of R'yleh great %s lies dreaming", 
           "In the halls of R'yleh great Cthulu lies dreaming", 
           " a stupid errorstupid errorHeystupid errors", 
           "stupid error", 
           " a ++Hey+s", 
           "foo barfoo barf", 
           "foo bar", 
    printf("\n\nTesting complete: check output carefully: \"Assertion 
failed\" should not occur!\n\n"); 
    return 0; 

A note on the mercy of the night

Posted in Uncategorized with tags , , , on December 25, 2009 by spinoza1111

Oh you men who think or say that I am malevolent, stubborn, or misanthropic, how greatly do you wrong me. You do not know the secret cause which makes me seem that way to you. From childhood on, my heart and soul have been full of the tender feeling of goodwill, and I was even inclined to accomplish great things. But, think that for six years now I have been hopelessly afflicted, made worse by senseless physicians, from year to year deceived with hopes of improvement, finally compelled to face the prospect of a lasting malady (whose cure will take years or, perhaps, be impossible).

– Beethoven

…fighting one Peter Seebach at comp.lang.c.moderated on Google Groups. He’s the author of the Vicious Tirade “C: the Complete Nonsense” which went viral and damaged Herb’s reputation.

But I am well aware that to defend a “reputation” is an antique gesture. Many younger corporate types don’t understand the concept.

It’s connected with the disappearance of the positive use of the word “man” as in “act like a man”.

“Man” does not and has never defined what it is to be human. “Men” have always been the first to acknowledge the other gender. At our best, we protect and shelter women when they most need it. And despite all their claims that they don’t, there are times when they do, such as birthing time. Indeed, “feminist” women are if anything far more demanding at this time.

But some sort of sick misunderstanding of feminism, coupled with widespread divorce and family abandonment by men of their families makes younger “men” contemptuous of the very idea of a “man’s” reputation.

The problem was that in the 19th century, a man was a standalone signifier accidentally associated with a wife and children, and represented them even in the electoral system, in which it was said that his vote represented the interests and desires of his family.

Today, it seems O.K. for people to say and perform the vilest sorts of things with respect to individual reputations. For example, I found a claim last night by one Richard Heathfield that I was never permitted to post on the prestigious and competently moderated ACM based group “Forum on Risks to the Public in Computer Systems”.

It was a malicious lie intended to defame and stupid because so easily refuted; a search of the archive finds 37 moderated and accepted submissions.

Nonetheless a post-human troglodyte “freedom” demands that I take this kind of shit lying down. On wikipedia, people who seem to me to be deficient are actively proud of their ignorance, as if it gives them objectivity, and pictures of “wikipedians” are frightening, for they seem doughy, vacuous, even mildly retarded en masse. And…this is confirmed when you discover 14 year olds and convenience store clerks “editing” your content.

I’ve seen software, programming languages, computers and corporations become more valued than human beings as such, with older men taking the brunt of a generalized, post-human lack of decency. Don Delillo, in Falling Man, has a divorced older man get a call from an ex-wife after 17 years of silence on Sep 11. She wants him to turn on the TV after having refused calls from him about their kids for 17 years as if her need to pass on an event he’d know about was more important than his contact with their children.

Wow, I thought, he’s got it down perfectly. That’s because after I relocated to China, I made a real effort, as I’ve made for thirty years, to maintain respectful contact with my former wife and loving contact with my now-grown children. But, in 2007, my former wife decided without explanation to refuse all calls and leave all email unread.

Like a prisoner in Guantanamo, I was not informed of the “charges”; when I asked her why she had made that decision after a period of time in which we were gradually healing our wounds by the exchange of simple gifts and cards at birthdays and Christmas, she refused to make any such explanation. It had, possibly, something to do with writings I’d posted on the Internet, although in 2000 (when I published a short story in a North Carolina literary magazine), I’d asked my former wife if she minded my artistic use of our marriage…and she’d said she did not.

Nonetheless, when she wanted to inform me of something, like the woman in Don DeLillo’s book, she would send me email in her old pattern: this was to inform me of a disaster involving my eldest son, who she has long mythologized as a fuck-up despite his stellar SAT scores and his ability to love, the latter being evident in a higher level of decency towards his father (but not much higher) and a brave openness towards finding love.

My kids followed her lead as always and suddenly I found myself the victim of treatment that seemed astonishingly cruel. My eldest son accepted my payment of his tuition for classes he needed to qualify for a job on the understanding, or so I thought, that he’d stay in closer touch through Facebook, but after the payment cleared, he said he’d made no such promise.

My younger son traveled several times to Asia (Laos, Vietnam, etc) without stopping in Hong Kong to see his father, or even explaining his reason for this. I have maintained contact with my own father consistently despite far harsher treatment that continues to this day (for example, after I took care of my father in an illness, he informed me that I was “worth less to him than his car”).

But when I sent an email to my younger son inquiring as to the reasons for his treatment, he replied by saying that he just didn’t care to see me but had no reason for this choice, it being his to make and not explain. When I persisted, he used my persistence as evidence of unreasonable behavior which retrospectively justified his initial coldness, in a sort of time warp (I’d grown accustomed to this years ago as a mechanism used by my former wife; they frustrate your Will, you respond either by flying off the handle or with calm prolixity, and either response, not being seen on TV from the TV dad, justifies their initial behavior).

For let us not speak falsely now the hour is much too late

Since I’m functional in other areas of life, able for example to set down in a foreign city and get a work permit and a job, and write a book, I don’t think I’m crazy, although (like my father, or Campari) I might be an acquired taste. But at one point last year, after I wrote a hand letter and a corresponding email from Paris on vacation to my former wife asking her to explain her behavior, she embedded what seemed to me my own grammatical and reasonable sentences in her reply as examples of unreasonable language.

Whoa…Gaslight time, as in the old movie where the guy monkeys with the gaslight to persuade the girl she’s crazy.

But it’s true that my language is sufficiently complex that it seems to hurt others. I feel like Beethoven, clumsily trying to have a semblance of a family relationship with his nephew Karl but failing because of his intensity, and in the final analysis, I don’t like hurting people.

At one point, I tried to go through my sister to arrange some sort of modus vivendi with the kids. I thought, silly me, wouldn’t it be great if my elder son communicated as a Facebook Friend and my younger son, the world traveler, came to Lamma Island. I asked my sister to be a go between.

I received an angry and off-topic tirade which implied, at least, that my internet postings were the problem, or maybe my effeminacy, or something. It was incredibly painful to get this, since it reminded me brutally of the many times when I’d go to my Mom for emotional support only to find her overwhelmed, and convinced that boys needed to be low-maintenance little men who would suck it up at an early age; I was bullied in the backyard of the family home with my Mom looking on, calling me a physical coward while sipping another Martini.

[Cue A minor string quartet which has just kicked in. Beethoven takes the pain and injects it in us straight here. The Mercury astronauts were taking off into space, and my Mom also informed me that I would never make an astronaut. The cruelty was occasioned by the fact that a larger local boy, whose parents were guests of my own and likewise swilling down the booze, was beating the shit out of me, and I was crying. He is now a Chicago millionaire. He half killed another neighborhood kid but it was hushed up.]

[Also cue Good Will Hunting, with Robin Williams saying over and over again, “it’s not your fault” to Matt Damon.]

This explains my Internet fighting, although my Internet fighting is, I believe (I believe) reality-based. I looked over the original document about Herb Schildt and verified that his errors were venial. I searched for corroboration and found instead that everybody was mentioning Seebach’s document, and a strangely similar document by one Clive Feather about another book by Schildt, and this was the sole source of information for the hate-Schildt crowd.

I found that the Internet echo chamber had created a “conspiracy theory” about Schildt.

But what’s interesting is the rapid evolution of bullying. Adorno, in his passage on the nightmare of childhood in Minima Moralia, says it evolved from childish pranks and tormenting in Wilhelmine Germany to grown men, regressing to childhood under the stress of war and inflation in Weimar.

Whereas in America, bullying evolved from a heavily testosterone-charged boy thing where one could get seriously injured in real fights (as I was in a fight on Plum Grove Road in Rolling Meadows in 1965 after “standing up” for a runty friend who was being tormented on the school bus) to a more emotional-abuse process, where boys, and men who haven’t grown up (and who’ve been in my opinion over-mothered and absent-fathered) use texts to abuse people, with no apparent upper bound on malice.

“Fight Club?” It’s a fantasy. Young men wouldn’t have the balls today to set up a real Fight Club, and they flee even email attempts to resolve online issues. My days of getting into real fights are probably over, although I got into a few rather jolly dust-ups back in Chicago when I was still drinking, ten years ago.

I need to go out for a Christmas Night run. Yes, I am Alone At Christmas and in the play-book, I’m supposed to Drown My Sorrows in Strong Drink.

Fuck that shit. Instead, I am going out into the great mercy of the night for a run.

A massive brain fart, or, when we were wrong promptly admitted it

Posted in Uncategorized with tags , , , on December 10, 2009 by spinoza1111

On comp.lang.c, I posted another request to Peter Seebach, the originator of the Vicious Tirade against computer author Herb Schildt who single-handedly created the rumor that Schlidt’s books are full of errors, but I mistakenly addressed Peter Seebach as, and confused him with, another Apress author, Peter Seibel. Seibel actually wrote in in puzzlement so this morning I submitted a clarification, starting with the admission of the error.

Now, as Dan Rather found out in the Bush “military record” forgery, the worst thing you can do when the “politics of personal destruction” are used against you is make an error, but the only sensible thing is to admit it, which I have at comp.lang.c.moderated.

But, the matter doesn’tend there. comp.lang.c.moderated is supposed to be a moderated group: but Peter Seebach himself is the moderator, and he allowed my erroneous post to go forward, seizing a chance as did Rather’s opponents (Dan Rather, in 2004, claimed to have found a document describing Bush’s evasion of National Guard service: the document was proven to be a forgery, produced by Microsoft Word: Rather was forced to leave CBS: but Rather is suing CBS because despite his error, he was right: the former President did indeed evade military service).

A competent moderator like Peter Neumann of comp.risks, or any adult, would have seen the error and contacted the poster for a clarification, but today many moderators (such as the head cases at the dysfunctional placeblog act like children, or worse. Seebach saw the error, saw a chance to embarass someone who’s criticised him for his treatment of Schildt, and allowed it to be posted.

I am pretty certain the matter will die out since I’ve only replied with my clarification and apology, and there’s no point in amplifying the matter. comp.lang.c, for a moderated group, is probably one of the worst groups online, and this is because Peter Seebach has no computer science education and confuses conducting a vendetta with discussing ideas. I won’t make it worse by amplifying this matter.

“In the matter of Herb Schildt”, continued

Posted in Uncategorized with tags , , on September 26, 2009 by spinoza1111

Note: for best results, read “In the Matter of Herb Schildt”, below, first.

Let us continue analyzing Seebach’s document, “C: The Complete Nonsense”

Herb Schildt wrote: “Memory allocated by C’s dynamic allocation functions is obtained from the heap — the region of free memory that lies between your program and its permanent storage area and the stack.”

Seebach’s reply: “C does not specify that there is a stack – only that functions can call each other. The “heap” is a DOS term, and the layout is not a part of the C language. It is not atypical for the layout to be radically different, and certainly, there is no call for describing a specific choice as “what happens”. “

C does not specify that a stack must be used at runtime to execute generated code, but it isn’t possible to explain how C works at runtime without using a stack in the most abstract sense: a collection of values accessed for read and write only at one end.

It’s impossible to execute C code, specifically direct or indirect recursion, without a stack: this can be proven by considering the runtime code as idealized bytecode, and showing that this runtime language is “Chomsky type 2”, a context-free but not regular grammar which requires a stack.

Because Herb was and is a real programmer, who has incorporated the essence of computer science’s basics more through experience (which is how the theory was developed in the first place) he prefers to phrase things operationally and in concrete terms.

But as such, Schildt violated an unspoken class divide: that students whose Mommies and Daddies send them to University have an edge denied veterans and the poor who attend computer school. Computer school trainers are often precisely unable to explain runtime semantics and they have traditionally excused their ignorance with saws of only minimal truth such as “you don’t have to look under the hood”, preferring students to learn by rote and regurgitation.

This produces programmers who cannot tell you whether or not And and Or in their language evaluates both sides in all cases, and who don’t care. It also produced, in my experience, programs which created reinsurance derivatives which failed to recognize indirect recursion.

The Standard, for a good reason and a bad reason, is silent on the exact mechanisms used at runtime for holding simple scalar values and for holding more complex values.

The good reason would be that someone might invent a replacement for the stack considered most abstractly as a collection of values accessed at one end, or a replacement for the heap considered most abstractly as a collection of values accessed randomly including free memory items available for assignment. However, no one has done so, it seems, and the Chomsky type hierarchy may indicate that it is not possible.

The bad reason is Seebach’s strange and crypto-Fundamentalist theory that C be taught without heresy in the form of predictive hermeneutics, which is what Herb is doing: applying one highly possible explanation (hermeneutic) to the given to predict what will happen at run time to code.

Furthermore: Seebach was wrong when he wrote that “the heap is a DOS term”. Heaps are in fact a well-known computer science “term”, and Seebach’s error, made while he was trying to destroy another man’s reputation, is of the same type as Schildt’s.

The mistake is called reification, mistaking constructed entities for reality. Below the level of data structure there is no stack, just bits and bytes: below the bits and bytes is electronics, and below that, physics.

Each level of description requires speaking as if certain things existed, and in the teaching environment, they have to be concrete to be understood. The teacher of a computer science 101 class will draw a memory on the black or white board, and will have to position the stack above or below the heap because he is constructing a concrete model of an abstraction which covers a wide variety of concrete implementations.

However, my experience is that corporations prefer to avoid concreteness and applied precision. Unless absolutely necessary, in the corporation, software is spoken of in the vaguest way possible. Any precise proposals are found to be wanting until the committee has found a least common denominator form of implementation.

It is said that “those who do, do: those who can’t, teach”.

Those who can neither do nor teach sit in the back of the classroom with superior smirks on their fat faces because they’ve read a standard designed to leave too much undefined lest compiler vendors have to hire help, and all they know is what is not true. They have no conception of the truth.

In the matter of Herb Schildt

Posted in Uncategorized with tags , , on September 25, 2009 by spinoza1111

Herb Schildt writes about the C programming language as well as other programming languages. Among many other titles, Schildt is the author of C: The Complete Reference and The Annotated ANSI C Standard.

Now, the “C Programming Language” is a widely used but somewhat flawed and somewhat out of date language. It was developed in 1970 at a turning point in American programming praxis, for it was only around 1970, during a highly self-critical period in American life, that a primarily European discovery was rediscovered in the USA.

This was the importance of being able to create structures explicitly in computer programs, both “subroutines” and “compound statements”, the latter being a set of primitive statements grouped using operators that functioned like parentheses: the words begin and end, or the left and right “curly braces” you see on your keyboard.

Subroutines allowed problems to be broken down into smaller sub-problems. Compound statements allowed logic flow to be expressed cleanly, in fact in three basic structures discovered in 1967 by Italian researchers Bohm and Jacopini: do something, do something while something else is true, if something is true do something otherwise do something else: Bohm and Jacopini proved that this was all you needed to write any program.

Both facilities allowed programmers to write more understandable code faster. Both were resisted, especially prior to 1970, in more pragmatic, business-oriented and American circles owing to machismo: it seemed to many programmers and their managers that although these facilities, and the restrictions they imposed on practice, were nice, they were at base “frills” that “real” programmers (code for “real men”) did not need.

However, by 1970, several major American computer projects, some of them associated either with the “guns” or the “butter” of Lyndon Johnson’s guns-and-butter “Great Society” had failed in part because they were written in languages that did not fully support subroutines (for example, by prohibiting a subroutine from directly or indirectly calling itself, something that seemed strange to early programmers as opposed to mathematicians familiar with “recursion”) or statement grouping.

Two of these projects were IBM’s operating system for the IBM/360 mainframe series announced in 1964 and the MIT Multics system, where the latter was intended to make computer power available widely through time-sharing.

Observing the failure of Multics and the arrogance of its developers, Kernighan et al. created unix as a smaller and simpler evolution, using at first something called BCPL and then C, which borrowed block structure and full recursion from Algol.

C virally evolved without any central standardization and by the beginning of the Nineties was a structured mess with the irritating property of making smart people stupid, for another feature of C (not taken from Algol) was aliasing. The machine address or location of any variable could be used using the full power of C meaning that it was impossible to predict what a given C program would do.


People don’t think like a “von Neumann” computer (essentially a row of numbered boxes, some of which contain data and others of which contain individual instructions which use the numbers of other boxes). People don’t think like a “Turing machine” (essentially a glorified tape dispenser mysteriously able to stamp, erase and read symbols on its tape, and move back and forth).

But by the 1930s, many people were expected to at least try to think like von Neumann computers (but most assuredly not like von Neumann) or Turing machines (but most assuredly not like Alan Turing) as a condition for working in American offices, Russian planning bureaux, or the concentration camp front office, as a precondition for delaying their destruction. Dehumanization became a fashion statement.

1940s office

One response is to learn to program, a working and lower middle class strategy of staving off the inevitable: but as it happened, the difficulty of programming, whether admitted or more usually not, has also stunted minds, causing them to unconsciously replicate barbaric myths…including that of the scapegoat.

C evolved in the West, and in the lands of the former Soviet bloc, as a technician’s rebellion against bureaucracy and was rhetorically associated with liberation, although it is questionable as to whether to find a way to better program computers, which are primarily used by organizations and the wealthy in ways that exacerbate inequality, is liberatory.

C’s passive aggression was its linkage with the computer languages that had caused the failure of Multics and OS/360. In many ways it was possible to write even more “obfuscated” code in C than it had been in IBM’s “assembler” language.

At the end of the 1980s, Herb Schildt appeared on the scene writing in a breezy and refreshing way about C. One way in which he was different was that he wrote a small compiler-interpreter for the C language, which gave him both an understanding of how C is actually run and the ability to explain the runtime semantics of C (the “meaning” of a C program) in a mathematically intuitionist way: constructively and step by step.

But at the same time, there was a drive to “standardize” C.

In the late 1950s, the standardization of programming languages, which required compilers of programming languages to follow sets of rules to be able to call themselves “standard”, was under the control of the military-industrial complex. But by the 1990s, Reagan-era privatization had taken over standardization and made it serve “business needs” where “business needs” had become in my direct experience less a rational cost-benefit analysis and more a mantra or shibboleth, the purpose of which in software was to stop thought and to stop any consideration of the “needs” of all but the wealthiest and least principled corporate stakeholders: programming an ATM interface in a way friendly to the actual person using the ATM became in some instances a termination offense since the actual user wasn’t important.

The result in standardization of C in 1989 and 1999 was that the process was almost completely driven by corporate demands as opposed to mathematical truth or even software engineering.

Basically, it appears to me that manufacturers had produced C compilers and in the “reduced instruction set computing” movement (designing computers with in some cases reduced and in all cases highly efficient in terms of speed instruction sets), the “business need” of these hardware and software manufacturers was to avoid having to change this code, because having downsized, and laid off more competent compiler developers, they didn’t want to rehire these people, or contractors skilled enough to attend and influence the conference, and change compilers. This breadth of ability has been pretty much eradicated in programming in America, so the corporate response was predictable.

Therefore, they high-jacked C standardization because “the public interest” in computing is no longer thought to exist.

Then, it appears that committee members nailed Schildt as non-standard because the process needed a scapegoat. Peter Seebach wrote a vicious little tirade and in the spirit of ape see monkey do, Clive Feather wrote another.

Here’s a technical example. C had had pragmatic little operators for adding one to variables, something programmers often have to do. If p is a C variable, p++ adds one to it while returning the value of p before it is incremented.

Circa 1970 it was quite common for designers of new programming languages to use the kitchen sink philosophy: Brian Kernighan, Dennis Ritchie, and Rob Pike, designers and developers of unix and C, tried to avoid this but could not resist in this case.

It turns out that the “postincrement” operator (along with operators for decrementing, and incrementing or decrementing before returning the value) was problematic. It did not separate the Ideas of a value in a register with a designation and a temporary homeless value.

When a programmer uses a+b, a and b are stored, on a von Neumann machine, in places with unique addresses but their sum exists in a nameless but known place, called in older computers a register, and referred to today, most but not all of the time, as the top of a stack of values.

Therefore C puzzles arose such as how p=p++ is evaluated and the meaning of (p+q)++. These were handled differentlby in different compilers.

However, p=p++ (not (p+q)++) can be rationally explained by using a simple model. Since the only sensible authority (then and now) on C is a book published in two editions by two of its founding fathers, Brian Kernighan and Dennis Ritchie, their non-systematic account of p++ means that in p=p++ p must have the incremented value with respect to its initial value although it will be set temporarily to its older value!

I have looked over Seebach’s and Feather’s writings on this matter as well as the prose of the C99 standard, and it seems that owing to corporate pressure, the committee responsible for the standard made itself collectively forget, in an irresponsible scientific pseudo-asceticism, the above distinction between a value in a nameless but available register (or the top of a stack) and a value in a von Neumann address!

Furthermore, they seem to have done so because some compiler manufacturers are vending compilers written by uneducated “compiler developers” who were unclear on this distinction, although understanding the von Neumann case (called an lValue) is essential to understanding C.

Again, and as in many other areas in programming, I am reminded of the collision between midcentury sociologist/musician/philosopher Theodore Adorno and his managers at the RCA-funded “Princeton Radio Research Project”.

Adorno discovered how committees work as a participant observer. They are (in radio research, programming, and many other areas) typically unable to agree on grand narratives unless they work in totalitarian societies, where the reverse is true with pretty much the same results.

Committees typically reject simple and elegant solutions because the stupidest members of committees are often the most powerful and they are the least likely to understand simplicity and elegance. These members often have a veto power denied to more intelligent members, and the result was the horror of Cobol in 1960, the horror of the C99 standard in 1999, and in Adorno’s day, a series of middlebrow programs on classical music which by rejecting Adorno’s suggestions, destroyed classical radio by the outbreak of World War II (in the 1920s, the majority of radio stations played predominantly classical music).

Furthermore, in both totalitarian and “democratic” societies, big men can’t be offended or threatened: but in the case of C, to force compiler developers to change their compilers to (say) prohibit applying increment and decrement to non-lValues would break both compilers and application code, and force corporations to hire and pay developers without a business case to be made; merely fixing the problems would not generate profits, and in the modern corporation, this is a non-starter.

Therefore, a scapegoat was found and this was Schildt, C99’s Robert J. Oppenheimer.

The standards efforts around C in 1989 and 1999 preferred to protect profits by declaring many common, if not very safe, uses of these operators, and similar ill-designed features of C, as “undefined”.
But in writing a practical book as almost the employee of McGraw Hill (where in my own experience as a computer book author, that is what you are) Herb did a workmanlike job in predicting, for pathological cases, what would happen.

He was taken to task by two people associated with the standards committees in what I think was an unprofessional manner.

Wearing the stolen mantle of priests of software safety, Peter Seebach and Clive Feather both published disorganized lists of “Schildt’s” errors.

They lacked the skills of English and the humanities to realize that there’s an alternative, if you care about software reliability and standards, to writing a laundry list of one man’s errors, and then making a joke out of that man’s name.

Edsger Wybe Dijkstra, an older programmer who’d died in 2002, had written extensively on software readability, maintainability and safety. But as a better-educated man and far more grown-up than Seebach or Feather, Dijkstra had the ability that an English prof would call “doing theory”.

Dijkstra would not acknowledge any link whatsoever between the “theory” that is a staple of English studies and his work, but I think there is.

Instead of naming and shaming, Dijkstra worked much harder than Seebach/Feather to define the “wrong way” as precisely as possible.

How did he do this?

Donald Knuth has been to my knowledge the only software author with enough education to recognize the relationship of Dijsktra to an alternative to the dreary Platonism of most mathematicians and philosophers of mathematics: the “intuitionism” or “constructivism” of Brouwer et al.

Platonist mathematicians and philosophers of mathematics believe that the truth of math is ultimately grounded on the real existence of ideal mathematical structures. Intuitionists, on the other hand, deny this, and insist that mathematicians confine themselves to declaring results only when they have “constructively” proved them.

In intuitionism, a “negative” proof, defined as one that argues the absurdity of the opposite of that which is to be proved, is forbidden. All other of the common tools of argument can be used.

I believe this is why Dijkstra was never content (in his writings as available in an online archive at the University of Texas) to merely criticise or name and shame. Instead, he was always driven to characterise what he felt to be wrong thinking anonymously, and then, in the “intuitionist” mode, to construct a working alternative model.

This is anti-Platonist. Derrida (yeah, the French guy) noticed that at certain points, authors and philosophers who do not ponder their Platonic committments tend to get down and dirty with their opponents. In Of Grammatology, Derrida shows that the Platonic committment emerges as an “aporia” in the form of an unconscious switch from reasoned, civil argument to hysteria.

Plato did this with the Sophist: his mouthpiece in the dialog of that name, Socrates, uses violent metaphors that cease being metaphors, such is Socrates’ anger at what Socrates regards as tricks of reason.

In the modern period, Derrida found, high Modernist thinkers such as Ferdinand de Saussure (the linguist who disconnected the magical link between word and thing) likewise would wax dogmatic and blow their stack when challenged with the implications of their own thought.

We in fact rely on Platonic assumptions about the existence of something higher, cleaner, purer, more real, and realer more than most of us are willing to admit.

What set Dijsktra apart was that instead of naming and shaming he tried most of the time to construct concepts whose existence in the real world would show alternatives to be flawed. One of his discoveries, for example, shows us today how to write programs which can be executing different “threads” of their code on the same data set at the same time.

Dijkstra also invented the interpretation of Bohm and Jacopini’s structured programming, as a good practice, because he was conscious of the need for the ordinary programmer (as opposed to TS Eliot’s “chairmen of many committees”) to actually construct the leading edge of history (like so many Hegelian slaves before and since, who polish the blade of the Juggernaut that crushes them).

Now, Schildt was no Dijsktra. However, like a lot of real programmers with whom I’ve worked all over the world, Schildt wanted his programs to work. He also wanted to explain how they worked.

He made mistakes, and there are mistakes and bugs in the printed code. Now, Brian Kernighan, along with unix and with C, also published a very good little book around 1976, on programming style, and in that book Kernighan (without naming and shaming anyone) had decried the fact that there was buggy Fortran code in a number of computer books of the time.

When I started work as a computer programmer and mentor at Princeton in 1987, I was introduced to Brian at a get together for former student employees of the “computer center”. This was my “Alice Cooper” moment, for I felt a bit like Wayne and Garth in Wayne’s World when they meet Alice Cooper: “we’re not worthy”).

we're not worthy

I asked Kernighan if he’d offended people, and he said he’d not. I believed him since instead of merely shaming, and without naming, Kernighan had suggested the alternative of using structured style in a language not thought suited to structured programming, and a layout that followed the style.

Seebach’s and Feather’s “alternative” is slavish obedience to a flawed standard which in many cases groans that what was coded is undefined. They seem to regard the standard as a teaching and learning tool, which is silly: standards manuals are neither.

Kernighan’s apparent hope, that printed code in books could be bug-free, has not been realized.

This is not only because of the conditions of production then and now of books in general cause errors to creep in at various points. Prior to digital typesetting (notably Donald Knuth’s work with Tex), there was an expensive and irreversible process at the typesetting shop.

After Knuth and in today’s conditions of production (where documents typically in some form of Word are transformed into Adobe PDF camera ready copy) errors can still creep in. Instead of being locked in by an irreversible and expensive process, they creep in today for the reverse reason: the ease of change causes changes as a form of mutation.

Now, Seebach and Feather have waxed prolix over time about Schildt’s printed errors. This I’m afraid shows that they haven’t thought through the definition of a programming language.

Knuth and Dijsktra converged, without to my knowledge communicating with each other, on this definition, which I shall paraphrase:

A programming language is a language for communicating “our” intentions in using computers, where “we” are people.

I shall repeat it because it’s quite a shocker.

A programming language is a language for communicating “our” intentions in using computers, where “we” are people.

A programming language is neither a mathematical formalism nor a collection of bits ready to load and execute.

While not completely clearing Schildt (or the editorial bureaucracy at his publisher) of the errors in his books, this definition puts his errors into perspective.

No programmer will scan Schildt’s printed code examples and use OCR to convert them to source code. Nor will a professional expect all code in any CD-ROM shipped with Schildt’s books to run perfectly.

It is indeed a scandal to me that the software industry, coming of age as it did during the fat years of Reagan in which selfishness was predominant, obtained for itself an exemption to the usual requirement that trade goods be reasonably fit for use. Like the tobacco companies of 100 years prior, whose products then and now are by definition unfit for use, the software companies obtained for themselves and their majority stockholders an exemption, to which you agree when you check a box while installing software.

Such a warranty appears on Herb’s books and the software shipped with them, and Herb is not at fault for this.

Nonetheless, a rather young and rather wet behind the ears Seebach made Herb take the fall because that is what systems do when they normalize deviance. The result was the long-running persecution of a hard working computer programmer and the embarassment online of his family, which did C and programming not a bit of good.

In future articles I shall take Seebach’s and Feather’s poorly-written and disorganized attacks apart, piece by piece. Let’s start here with Seebach‘s article “C: The Complete Nonsense”.

C: The Complete Reference is a popular programming book, marred only by the fact that it is largely tripe. Herbert Schildt has a knack for clear, readable text, describing a language subtly but quite definitely different from C. This page aims to give people a good way to find out what’s wrong with it.

A basic paradox is that Seebach and Feather continually concede that Herb is a “clear” and “good” writer without explaining how errors can be clear.

Don’t bother contacting the publisher; they apparently don’t feel these errors are significant.

Yeah, can you say “harassing McGraw Hill?”

The following is a partial list of the errors I am aware of, sorted by page number. I am not including everything; just many of them.

No real effort was made despite the seriousness of damaging a reputation, in other words.

I am missing several hundred errors. Please write me if you think you know of any I’m missing. Please also write if you believe one of these corrections is inadequate or wrong; I’d love to see it.

Sen. McCarthy 1954: “I have a list of known Communists”.

Page 19
In general, negative numbers are represented using the two’s complement approach…
This is not a C feature. It is a common implementation, but it is specifically not required. (Binary is, but one’s complement is not unheard of.)

We start with a whimper. How on earth does either a computer science 101 professor, or C instructor whose students haven’t had rich Mommies and Daddies send them to university, explain how negative numbers are almost always stored in a modern computer?

static Global Variables
No such thing. A static variable outside of a function has file scope, which is distinct from global scope.

This is the fat, bearded lawn troll in the little cubicle stuffing himself with junk food, holding a company to ransom with crap software, and admonishing all who will listen as to the meaning of words.

Call him Otto.

Otto is more anxious that we know that he knows more than us. Unfortunately, Otto creates, on balance, more confusion than Otto resolves.

In practice, the concepts are often the same, and in practice, this keeps things simpler for the tyro, my dear Otto.

“This shorthand works for all the binary operators…” [says Schildt]
No, it doesn’t. It doesn’t work for “.”, “->”, “&&”, or “||”. For that matter, it doesn’t work for the function call operator or the array operator, both of which are, roughly, binary operators.

Schildt is saying that shorthand operations such as += should best be thought of as available to all the most common binary operators by the programmer who only rarely uses the logical operators…eg., many business programmers, who historically have preferred to express logical operators using simple statements with if then else structures.

Words in other words, acquire local meanings as the most common instance in the teaching and learning context, and the best teacher uses this fact.

Seebach then tells us that the function call and array operators are “roughly” binary operators, giving himself the license he denies Schildt, because his basically Fascistic goal (yeah, you got that right) is to silence Schildt and advance himself in a zero sum game.

There’s more…lots more. Just to wrap up here, Seebach takes Schildt to task for describing runtime semantics using a stack model, and last month, an extended discussion in that intellectual slum Google Groups revealed that Seebach, a participant, preferred that Schildt not describe runtime semantics, and that no participant could actually identify a mechanism, other than a stack, to execute code written in a language with recursive procedures.

In fine: Seebach seeks to destroy programming education outside of expensive universities insofar as he won’t let the programming trainer described, to the best of his ability, by way of an example which might admit a jot or tittle of what might actually be “out there”.

This is a nasty Fundamentalism because it’s isomorphic to the religious Fundamentalism of the Puritan who’d rather people be silent on religion: some historians attribute the rise of secular theater in Elizabethan times to Puritan fears that the common people’s traditional “mystery” play might err and blaspheme.

We got Shakespeare from that, but from Seebach’s fundamentalism we get more untrained programmers who cannot sensibly describe how their programs execute, because their teachers have been silenced. And, Puritan fundamentalism is bad enough. Fundamentalism in the name as something so trivial and nasty as mere computer software is anti-human.

To be continued.