P
Phil Carmody
Done. Bye.
Hohoho, we have a joker in our midst. What are the chances he
still wastes bandwith responding to spinoza1111...
Phil
Done. Bye.
Seebs said: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.
Richard Heathfield said:Nick said:On Feb 22, 9:15 pm, Nick Keighley <[email protected]>The beginning of wisdom for a [software engineer] is to recognize the
difference between getting a program to work, and getting it right.
-- M A Jackson, 1975
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.
When I heard that Michael Jackson had died, I was (a) somewhat
saddened, but not surprised (he's in his 70s, after all), and (b)
somewhat puzzled at all the public fuss. Thoroughly merited, but
rather unexpected nonetheless.
As it turns out, though, there are several Michael Jacksons, and it
was one of the others that had died.
santosh said:Even if I were a very good C programmer, I'd object to any publisher
who decided to describe me as "world famous programmer" on any C book
I were to write. Not everything is about marketing. I know evaluating
a book based on an emotional reaction to it's blurb is weak, but
still...
Chris M. Thomasson said:Seebs said:Anyone planning to invent this would be well-served by studying the
"mbufs"
in the BSD networking stack.
Indeed. I also enjoy the well known intrusive list technique:
_______________________________________________________
struct node
{
struct node* next;
};
struct foo
{
struct node node;
/* [whatever] */
};
#define foo_from_node(n) ((struct foo*)(n))
_______________________________________________________
The Linux User/Kernel and Windows User/Kernel-space code is quite fond of
intrusive data-structures as well.
spinoza1111wrote:
<snip>And where, pray tell, are you going to *store* your elements?
In another object? Well, I personally enjoy embedding list nodes directly
into elements:
__________________________________________________________ [...]
__________________________________________________________
This way I do not have to allocate a seperate node to hold a pointer to
the
element. Humm... I think there are basically three ways to do this. [...]
A very good solution, but if you have multiple ways of chaining data
together, you're going to have to have arrays of nodes.
And it doesn't
solve the problem addressed in C Unleashed which was to create a
reusable tool for handling linked lists.
You could write reusable software for handling pure node structs, but
that would necessitate a "callback" when you get to the problem of
comparing two linked lists for identity, or searching the list for a
value.
The problem of linked lists is elegantly solved in your way in OO
code, since you can inherit a List and put your own data in it.
The problem is that Richard's "reusable" software only seems to have
considered one way, and this was a way that copies O(n) bytes and
creates the risk of having two copies of data. To be truly reusable it
needed to support three alternatives: linked list of copies, linked
list of pointers, or a pure linked list such as yours consisting only
of links to the next element (one with "null" data).
Agreed.
But this would have involved more advanced use of the preprocessor. My
complaint is the implicit presentation of only one way without
discussion of the alternatives, in the manner of the Fundamentalist
that Richard appears to be.
Richard Heathfield said:That's an easy one. It's because he's an idiot.
No, by that time I'm usually fed up.Ahh.
And so I see.
...
D'oh! AND THE LIGHT GOES ON!
I think I have come to understand why it is thatspinoza1111has consistently
missed these things.
Have you ever noticed how some of his posts have quoted material ending with
something like "Show quoted text" or "read more"?
I betcha that, if you were to look at the posts in which I first pointed that
out in Google Groups, you might find that my explanations were *below* that
line. And in general, he has consistently failed to respond to information
past that line, suggesting that he doesn't know how to show the rest of the
post.
Which might explain why he's never responded to or acknowledged the multiple
times I've said this. But not all of them:
This brings up a vaguely topical question:
Can anyone name a dialect of C that has ever not supported variable
initialization?
MS is not famous for great compiler work, or for reasonable default
options.
By the time the third edition of CTCR (the edition on which CTCN was
based) was written, the ANSI Standard was already six years old.
No, in 1995 (when CTCR3 was written), the ANSI C Standard was very
widely supported.
Richard said:Would that they did. Then the quality of software might improve a bit.
Putting the bug aside, I had experience of people writing C like that
around 1990. They'd been on some sort of course in some sort of
programming methodology (maybe SSADM, maybe not - it was a long time
ago). In this case, they ended up writing something like:
a = fgets(buff, SIZE, stdin)
while(a) {
do_things_with_a;
a = fgets(buff, SIZE, stdin);
}
All perfectly logical, but utterly un-idiomatic and (particularly when
things were a bit more complicated) it led you to looking at the two
identical lines wondering if they were in any way different.
Ian Collins said:Why should they? If you want to analyse code, use a tool like
lint. Let the compiler focus on compiling legal code quickly and
accurately.
MS is not famous for great compiler work,
I thought these days they were. Apparently they "eat their own dog
food". Though some would argue failure to support C99 is a gaping
hole.
or for reasonable default options.
which compiler *does* come with reasonable default options!
There's no fundamental reason why a compiler can't do as
much analysis as it likes, perhaps optionally. Much of the analysis
is necessary for optimization anyway.
Nick Keighley said:On 23 Feb, 20:16, Nick <[email protected]> wrote:
it's idiomatic in a language that doesn't allow assignment in the
test. Removing the duplicated line was one reason I liked C!
It may be "idiomatic" but it is not good style in any language. If
you can't put an assignment in the test (because the language does not
allow it) then I think the way to go is an input function:
while (can_get_input(&a))
do_things_with(a);
Ersek, Laszlo wrote:
) In article
<0.b03829bbcb6aa0133e99.20100224124328GMT.87zl2yls7j.fsf@bsb.me.uk>, Ben
is not good style in any language. If )> you can't put an assignment in
the test (because the language does not )> allow it) then I think the
way to go is an input function: )>
)> while (can_get_input(&a))
)> do_things_with(a);
)
) Or we could commit a little bit of style massacre: )
) for (; {
) char buf[SIZE];
)
) if (0 == fgets(buf, sizeof buf, stdin)) { ) break;
) }
)
) /* ... */
) }
That's just plain silly; you moved the while() condition into an if()
condition with the exact same semantics.
I think you meant:
for (; {
a = fgets(...);
if (a == 0) {
break;
}
...
}
do {
a = fgets(...);
if (a) {
...
}
} while(a);
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.