Efficency and the standard library

S

Seebs

Hard to say. It's inefficient, but not necessarily wrong.

The code he gives using it is, in fact, consistently wrong. He does loops
of the form:
while (!feof(fp)) {
c = fgetc(fp);
fputc(c, fp2);
}

(simplified, but that's the essence).

Which is to say, loops which will in general try at least once to pass
EOF to fputc.

-s
 
B

Ben Bacarisse

Seebs said:
The code he gives using it is, in fact, consistently wrong. He does loops
of the form:
while (!feof(fp)) {
c = fgetc(fp);
fputc(c, fp2);
}

(simplified, but that's the essence).

Which is to say, loops which will in general try at least once to pass
EOF to fputc.

Consistently? I am not so sure. Listing 7 in chapter 9 seems to be
"fixed":

/* This code actually copies the file. */
while(!feof(in)) {
ch = getc(in);
if(!feof(in)) putc(ch, out);
}

Of course, not only is this not the idiomatic way to do IO in C, but
it fails to handle read errors. In another example (chapter 22 listing
16) the check on fread saves the day:

while(!feof(fp)) {
info = (struct address *) malloc(sizeof(struct address));
if(!info) {
printf("Out of Memory");
return;
}
if(1 != fread(info, sizeof(struct address), 1, fp)) break;
dls_store(info, &start, &last);
}

but the break causes a memory leak. In yet another (chapter 29
listing 9) a loop that looks wrong:

i = 0;
do {
*p = getc(fp);
p++; i++;
} while(!feof(fp) && i<PROG_SIZE);

is not quite as it seems because the string, p, is terminated by
overwriting EOF that gets read in. It still manages to fail on empty
input, though, because what follows is:

if(*(p-2) == 0x1a) *(p-2) = '\0'; /* null terminate the program */
else *(p-1) = '\0';

which has undefined behaviour when the input is empty.

In other words, there are lots of loops that are wrong but they don't
seem to be consistently wrong. Even the fact the feof testing often
misses read errors is not consistent as the example with fread shows.

There are simple cases of processing the EOF (chapter 9 listing 10 for
example) but the problems are not always that simple.

NOTE: I don't have this book so some of these may be explained in the
text: "don't do this" or "this has a problem that will be sorted out
later" although that does not seem likely.
 
S

Seebs

Consistently? I am not so sure. Listing 7 in chapter 9 seems to be
"fixed":

Ooh, interesting.

You are right about at least some of them. He offers the sample code:

while(!feof(fp)) ch = getc(fp);

which is questionable.

The loop in the next example is (oh, I see you quoted it):
/* This code actually copies the file. */
while(!feof(in)) {
ch = getc(in);
if(!feof(in)) putc(ch, out);
}

That fails if it gets errors but will handle an error-free read correctly,
even though it's expensive and poorly written.

I'm quite impressed by the example on page 237 (a bit earlier):

do {
ch = getchar();
putc(ch, fp);
} while (ch != '$');

I'm pretty sure you can spot the problem here.

This is then followed by the "corresponding" example:

ch = getc(fp); /* read one character */
while (ch!=EOF) {
putchar(ch); /* print on screen */
ch = getc(fp);
}

This is actually probably correct, though horribly unidiomatic. Oh, wait,
found the bug; it's worse. "ch" is declared as a "char", meaning that on
many systems, it will spew an infinite stream of characters which have the
value you would get if you converted EOF to char. Since the entire POINT
of EOF is that it's a value which cannot be a character returned by getc,
and thus, is outside the range of unsigned char, that's sort of bad.
In other words, there are lots of loops that are wrong but they don't
seem to be consistently wrong. Even the fact the feof testing often
misses read errors is not consistent as the example with fread shows.

You're right, though, it's not "consistent". It's actually amazingly
inconsistent. If I were writing a book, I think I would at least standardize
on whether or not if() and while() got spaces before the leading parens. His
answer is that they almost never do except sometimes they do.

There's a bunch of crazy in here. He's got a large example which uses
completely unchecked calls to gets() to populate several fields of a
structure, for instance.

He really doesn't seem to comprehend that getc and the like return something
which is not necessarily a char.

-s
 
S

spinoza1111

Ooh, interesting.

You are right about at least some of them.  He offers the sample code:

        while(!feof(fp)) ch = getc(fp);

which is questionable.

The loop in the next example is (oh, I see you quoted it):


That fails if it gets errors but will handle an error-free read correctly,
even though it's expensive and poorly written.

I'm quite impressed by the example on page 237 (a bit earlier):

        do {
          ch = getchar();
          putc(ch, fp);
        } while (ch != '$');

I'm pretty sure you can spot the problem here.

This is then followed by the "corresponding" example:

        ch = getc(fp); /* read one character */
        while (ch!=EOF) {
          putchar(ch);  /* print on screen */
          ch = getc(fp);
        }

This is actually probably correct, though horribly unidiomatic.  Oh, wait,
found the bug; it's worse.  "ch" is declared as a "char", meaning that on
many systems, it will spew an infinite stream of characters which have the
value you would get if you converted EOF to char.  Since the entire POINT
of EOF is that it's a value which cannot be a character returned by getc,
and thus, is outside the range of unsigned char, that's sort of bad.


You're right, though, it's not "consistent".  It's actually amazingly
inconsistent.  If I were writing a book, I think I would at least standardize
on whether or not if() and while() got spaces before the leading parens.  His
answer is that they almost never do except sometimes they do.

There's a bunch of crazy in here.  He's got a large example which uses
completely unchecked calls to gets() to populate several fields of a
structure, for instance.

He really doesn't seem to comprehend that getc and the like return something
which is not necessarily a char.

We had fed the heart on fantasies,
The heart's grown brutal from the fare;
More substance in our enmities
Than in our love; O honey-bees,
Come build in the empty house of the stare.

- WB Yeats

Why are you so obsessed with Schildt? There certainly seems "more
substance in your enmities than in your love" if you could not be
bothered with taking a single computer science class but are willing
to rehash his "errors" while making your own.

Your conduct with respect to Schildt constitutes libel every time you
make any invalid inference or generalizations about his knowledge and
qualifications from typographical errors and even bugs, given
disclaimer of warranty, something that also protects you from your own
not inconsiderable incompetence in C, which was recently on display.
It also constitutes stalking in many jurisdictions, since he was a
private person as a contract-style employee of McGraw-Hill: you should
be aware given Apress' treatment of its authors that "computer book
author" is nothing more than "temporary employee" from the viewpoint
of publishers, and that authors are almost never given enough time to
do a complete job...because publishers, like software vendors, are
indemnified by the typical book or software warranty.
 
S

spinoza1111

fair enough. But you need at least one date structure to hold the
actual data.

Data structure, not date structure. Proofreading is a minor
programming skill, isn't it.

Yes, you "need" "at least one" "date" "structure". But making a linked
list is at base creating a view of data and it needs to support a
minimalist way of creating that view. Copying the data is one extra
function point which can go wrong when there is a lot of data.
no. You are confusing two different sorts of link. Linked lists are so
called because the nodes that comprise them are linked together. The
question as how the data is held (embedded or linked) is orthogonal.

"Orthogonal" is here misused since in CS it means "providing a
complete set of features naturally", not "an independent question".
With very small data structures or few copies then copying may make
excellent sense.

The problem is that Richard's "reusable" tool provides ONLY copying
when in C you can as I have said use preprocessor macros to support
pointers.

not really.

The grave negative isn't very informative, is it? But it does protect
oneself, does it not?
yes, exactly

But the default for big data is that the scope is completely under the
control of the programmer, since it is mallocated and freed.
I haven't seen this


"well done Karl!"

The fact is that programmers are victims of capitalism. Well done
Karl, and Che, and Hugo. Hasta la victoria siempre.
spinoza is making the wrong distinction. It's not lack of abstraction
that is the problem, but lack of strong typing.

The only way to overcome this is using the preprocessor, which means
that C is an inadequate tool.
a handle? As in a small integer.



I've seen you use this phrase before. Is it american in origin? What
does it mean?
It means I grab my John Thomas, my dick and balls, and tug at it while
rolling my eyes and tongue.
I'm not as much of a fan of the preprocessor as you obviously are.
Wouldn't tagged data give you what you want?

I don't know. What is tagged data?
 
S

spinoza1111

On Sat, 20 Feb 2010 23:52:03 -0800,spinoza1111wrote:
In the worst case, [shildt]
may have believed, as have many competent C programmers, that feof's
design wasn't <erroneous>, and that you could use it BEFORE the read that
fails owing to eof.
So you're saying he can't read?  After all, he had the very definition of
the mechanics of feof, from the standard itself, right in front of him -

not necessarily
he was, in fact, annotating that very standard.

we are talking about two different books he didn't necessarilyt write
them both at the same time.

What was irritating about Schildt and his publishers is that they made
no attempt to correct the errors (eg. issue an errata, correct them in
later editions). None of the errors were rocket science stuff but they
were very bad to have in a beginners book.

McGraw Hill offered Peter Seebach a JOB in helping out. He REFUSED and
went off to make his claims which themselves were unreviewed
collegially and contained their OWN set of errors such as his claim
that "the 'heap' is a DOS term" and foul language ("Bullschildt")
which he has removed in a cover up.
now there's a challege. I've read some pretty poor books. There must
be a *really* bad one on C. "C In 21 Days"?

Intellectuals don't use the phrase "bad book". Religious
Fundamentalists and other crazed nutbars do.
wha? Nowing how to use feof() is /error/?!

Yes, it's ersatz knowledge of a manufactured mistake which occludes
genuine scientific knowledge.
I came from Pascal and I had trouble with feof(). So I read the
documentation more carefully. Now I understand feof().

The metaphor here comes indirectly from Heidegger and his "jargon of
authenticity". Rather than face the fact of being servants of a
military industrial complex, programmers of the 1970s decided, under
the malign influence of silly movies such as Star Wars and sillier
books such as Lord of the Rings that they could maintain the fantasy
that they were "rilly" cute, fuzzy little "craftsmen" in "workshops"
using "tools".

But a reading of British historian EF Hobsbaum on Victorian craftsmen
shows us that locomotive maintenance engineers and other craftsmen had
the right to bring their own tools to the job site and to be paid for
cleaning that personal property at the end of the day. Whereas
programmers almost never choose the programming language they must
use, and never own the compiler.

The result? A requirement for employability is a slavish and
uncritical attitude towards "tools" in which "being a good C
programmer" is logically independent of "being a good programmer".

For which "software engineering" has had thirty years to give a
scientific procedure, and software engineering has failed. The guy who
flew the plane into the building last week was a software engineer.
 
M

Malcolm McLean

So, is double main(double) correct C?
It could be correct C. In an embedded system main might not be a
reserved identifer. The system might also (unusually) allow the OS to
pass arbitrary parameters to main.

It's not correct ANSI C for a hosted environment.
 
S

santosh

Malcolm McLean said:
It could be correct C. In an embedded system main might not be a
reserved identifer. The system might also (unusually) allow the OS
to pass arbitrary parameters to main.

It's not correct ANSI C for a hosted environment.

It is correct if the implementation defines it. While an
implementation defined prototype for main is likely not portable,
it's not incorrect C, AFAICS.
 
N

Nick Keighley

fair enough. But you need at least one [data] structure to hold the
actual data.

Yes, you "need" "at least one" "[data]" "structure". But making a linked
list is at base creating a view of data and it needs to support a
minimalist way of creating that view.[/QUOTE]

you could load the data into a linked list and then have other
structures point to it.

Copying the data is one extra
function point which can go wrong when there is a lot of data.

doesn't seem a particularly error prone area.

"Orthogonal" is here misused since in CS it means "providing a
complete set of features naturally", not "an independent question".

wikipedia:
"Computer science
Orthogonality is a system design property facilitating feasibility and
compactness of complex designs. Orthogonality guarantees that
modifying the technical effect produced by a component of a system
neither creates nor propagates side effects to other components of the
system."

The problem is that Richard's "reusable" tool provides ONLY copying

as does the C++ STL

when in C you can as I have said use preprocessor macros to support
pointers.



The grave negative isn't very informative, is it? But it does protect
oneself, does it not?

links could be indices into arrays

The fact is that programmers are victims of capitalism. Well done
Karl, and Che, and Hugo. Hasta la victoria siempre.

Python quote

The only way to overcome this is using the preprocessor, which means
that C is an inadequate tool.

no, the preprocessor isn't the only way.

I don't know. What is tagged data?

you put some sort of marker in the data to indicate its type. I'm not
sure how you are using the preprocessor or why you are so insistent
that your way is the only way.

I would probably write a generic void* based linked list then wrapper
it with something that was type specific. That might involve the pre-
processor or a simple code generator.


--
I have found that all ugly things are made by those who strive to make
something beautiful and that all beautiful things are made by those
who
strive to make something useful.
-- Oscar Wilde
 
N

Nick Keighley

<snip>

[in Pascal]
The one comment I recall from both personal experience and the writer of
a particularly interesting review of Pascal went something like this:
"Not only is Pascal limited, but you cannot work around its limits."

My first quasi-serious project in Pascal (oh, so many moons ago) was to
write a text-mode windowing system.  It was all very cool, very fast,
very sexy.  It would record the original screen state and restore it on
closing.  It understood z-levels.  It updated only the parts of the
screen which actually needed updating - occluded windows, for example,
did not cause screen updates.

I wanted very much to create a whole set of output routines, up to and
including windowed versions of write and writeln (print and println?  
Been so long I don't recall the standard names there.)

Thing is, you *could not do it*.  The language offered no functions, no
features, no mechanism for writing variadic functions; the one or two
which were part of the language were "magic", with the magic bits
handled, behind the scenes, by the compiler.

yes. I've never wanted to write my own varargs functions until I got
to C so it never bothered me (plainly I liked my blub)

Net result, while I could do *almost* everything I wanted, I could never
get quite the desired result, and the language itself - at least at the
time - offered no means to work around this.

"there is no escape" as Richie put it

Yes, presumably, later versions of Pascal offered such functionality,

nope. Various very non-standard versions of Pascal (Borland, various
Mac Pascal compilers and others) offered various solutions. But
standard pascal was pretty stuck (the string problem go sort of
solved). This was why C was so nice- the standard version of the
language was a complete languge! wow!

but
by then I'd become concerned about the fact that code using such
"enhanced" functionality wouldn't work even on different compilers on the
same OS, never mind on different OSen, so the options were to stick to
Pascal's fundamental limitations, stick to a particular implementation,
or scrap Pascal entirely.
yes

Voila, I'm a C programmer now.  Whatever faults C may have, stopping me
getting things done is very, very rarely one of them.

And I hated C when I started. It looks like line noise!
 
N

Nick Keighley

There are better books on C. [than Schildt's]
It would be difficult to find one worse.
now there's a [challenge]. I've read some pretty poor books. There must
be a *really* bad one on C. "C In 21 Days"?

Intellectuals don't use the phrase "bad book". Religious
Fundamentalists and other crazed nutbars do.

once you are on technical subjects there really are "bad" books. If
its wrong its bad. Hell even subjects like English literature or
economics can have bad books if they are badly written and
misrepresent the field's general concensus of opinion.

For which "software engineering" has had thirty years to give a
scientific procedure, and software engineering has failed.

only because Michael Jackson dropped out of programming to pursue a
popular music career.
 
R

Richard Tobin

Nick Keighley said:
only because Michael Jackson dropped out of programming to pursue a
popular music career.

It was the effect of all that beer and whisky.

-- Richard
 
S

spinoza1111

On Sat, 20 Feb 2010 23:52:03 -0800,spinoza1111wrote:
There are better books on C. [than Schildt's]
It would be difficult to find one worse.
now there's a [challenge]. I've read some pretty poor books. There must
be a *really* bad one on C. "C In 21 Days"?
Intellectuals don't use the phrase "bad book". Religious
Fundamentalists and other crazed nutbars do.

once you are on technical subjects there really are "bad" books. If
its wrong its bad. Hell even subjects like English literature or
economics can have bad books if they are badly written and
misrepresent the field's general concensus of opinion.

The problem is that the judge of a "bad" book has to be at least as
formally well-qualified as the author of the "bad" book, and Seebach
was not, not having studied computer science and possessing an anti-
Microsoft bias. He was correct in saying that there were bugs in the
code samples, but was unaware that this is a common problem in
computer books.

No reputable authority on C has criticized Schildt except where those
authorities used the C FAQ on Schlidt, and this was based on Seebach.
To most balanced commentators at the Amazon sites for Schildt's books,
the errors are de minimis because (as Seebach concedes) Herb's clarity
contributes to understanding.

It would have been better had Herb's code been reviewed by a C
specialist, possibly Seebach himself, but Seebach refused McGraw-
Hill's offer of a tech reviewer slot. Good programmers have good
expectations and are unfamiliar with idiomatic mistakes, and a C
specialist's input would have improved the final result.

Blame the system, and blame Seebach for being unwilling to work for
McGraw-Hill. Schildt has made too many contributions over the years to
make his name a byword.
For which "software engineering" has had thirty years to give a
scientific procedure, and software engineering has failed.

only because Michael Jackson dropped out of programming to pursue a
popular music career.
 
B

blmblm

[ snip ]
Because in fact men have been in most societies definitional of full
humanity. This is unfair to women but the fact is that in patriarchal
societies most women haven't been independent enough for us to make
all but a few (Joan of Arc, Marie Curie, Sophie Germaine) into
exemplars of what it is to be human.

When I use the words, "act like a man" I mean acting like a free and
independent moral agent who tries to do the right thing, like my
father for example, or me at my best. I think most of the male posters
here are not men but guys.

I'm inclined to think that the admonition "act like a man",
addressed to a woman, means something different from the same
admonition addressed to a man. But it's possible I'm being
influenced by the difference between "he acts like a man"
(almost invariably positive) and "she acts like a man" (in some
contexts negative). "Whatever", maybe.

[ snip ]
 
B

blmblm

[snips]

No argument there, none whatsoever. But lemme ask you a question. Where
the **** do you get off criticising people who are, if not perfect,
better than you? People like Schildt?

[ snip ]
Arguably, McGraw Hill should (or should have, when the book was
published) devote/d more resources to debugging, and that they were
inclined to do so was indicated that they offered Peter Seebach, who
they did not know, money to participate. He refused their offer, he
tells us, because it wasn't enough...money.

Has he not said, in this discussion, that in hindsight that might not
have been a good decision? People with little experience of the world
sometimes make decisions that they later recognize as mistakes. Why
keep bringing up a decision that has already been admitted by, um,
the decider, to have been flawed? (Rhetorical question, really.)

[ snip ]
 
B

blmblm

[ snip ]

[ snip ]
Thanks for finding this bug, Professor!

In the context of these discussion (and also in your change record),
"BL" or "Ms" is fine. (I would actually not mind *not* being credited.
Up to you, maybe.)
Yes, you are correct. I did not initialize the ptrSegmentStructStarts
pointer and the program failed on a null master string. Since it is
without meaning to search for a null target, I'd inserted a check for
a null target, but a search in a null master is correct.

I'd been laboring under an incorrect presumption, which was that the
dialect of C supported by Microsoft C++ Express .Net in C mode does
not support variable initialization, therefore I'd initialized
selectively and "by hand". I was also mistakenly under the impression
that the pointer would get initialized inside the loop the first time
a structure instance is created but NO instances need be created, nor
are created, for null masters.

Interesting that gcc warned me that variable might not be properly
initialized, and apparently the compiler you're using didn't ....
Then again, I almost always compile with flags that generate extra
warnings; when I compile without those, I don't get the warnings
about possibly-uninitialized variables. Maybe the compiler you're
using also has some settings that would have helped you avoid this
bug?

[ snip ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,122
Messages
2,570,716
Members
47,283
Latest member
VonnieEwan

Latest Threads

Top