Common misconceptions about C (C95)

S

spinoza1111

While Kenny may well be trying to destroy this newsgroup, I am pretty
sure Spinny's merely crazy.

Perhaps. But I don't think so. And contrary to the caricature, crazy
people don't usually have the ability to reply in verse, esp. not
comic verse. And your comments have been (esp. from a person who's a
colleague in the sense we've both published at Apress) very
unprofessional, very offensive, and almost content-free.

Furthermore, it is deeply ironic that you are ready to label people
"crazy" when on your blog and here you seem to be "trolling" for
sympathy for your own various ADHD disorders, and how you have to take
medication. How are we to know whether your obsessive and compulsive
replies to criticism, and indeed your attack on Schildt, were not
crazy in themselves?

Perhaps your insistence that people who disagree with you must be
crazy is in fact a Trogdolyte's *tu quoque*. Rather than claiming
positive knowledge, you prefer a skepticism that is in fact and as far
as I'm concerned an artifact of an excuse for the aporias in your
education, in English and compsci. So everybody's crazy to you, and
you're the craziest of the lot.
 
S

spinoza1111

Quite possibly; I won't attempt a diagnosis.  But the conclusion is
the same either way.

The purpose of "killfiles" is to end contact between people who don't
like each other. It's not to allow people to make claims about others
that they know the others will see and that will harm them to the
point of being legally actional.

So if I were your attorney, I'd advise you to shut up, Mr. Thompson.
 
S

spinoza1111

Which is why its a terrible analogy.

There is nothing wrong with a compiler book which dedicates itself to
one part of the overall system.

Only a complete idiots would take off in a plane learning from a book
which only includes the how to take off part.

....Unless he is a highjacker, ha ha. Not funny, I know.

What's missing in the attacks, Richard, is that in business
programming there's a need for non-optimized compilation of business
rules for any application where those rules are too complex and
changing to be hard coded. I wrote the book to show how to do mainly
the front end because I'd discovered in business programming quite a
number of cases where it was easier to build a language to express
solutions to the problem than build a hard-coded solution that would
be hard to change.

What irritates some folks here is writing pure and simple.

Deceived by the only apparent precision and infinitude of their
computers, they pull a book off the shelf about a subject they think
they know, and read it filled with resentment, especially at writers
who write clearly. This is due to their own failures to articulate
what they know as in disastrous "training classes" they've delivered.

Therefore they are ready, as techno-fundamentalists, to set themselves
up as *imams*, and issue *fatwas* against *kafirs* who write Satanic
Verses as if C would not survive, being the destructively immortal
virus it is, the books of Schildt...as if Nilges was actually saying,
"**** the back end, you need only write an interpreter"...which he did
not, any more than Schildt said that C MUST use twos-complement.

Nilges was saying that to Get Started, to enter the shallow and almost
flat part of the learning curve, you might as well begin at the
beginning.

Code generation and optimization contain interesting challenges (and
my book includes some examples, including the issue of how to do
compile-time constant evaluation right and in the same way as
runtime).

But IF a language like C can exist, wherein actual parameters are
evaluated in a non-orthogonal reverse order for the convenience of run
time, then the front-end was never mastered in C. Nobody ever made up
their mind whether left to right evaluation should be honored.
 
S

spinoza1111

I'm wondering how on earth people can play with this analogy at
all. It's ridiculous.

I did bring in the plane for a landing, if we must use this absurd
analogy, for the compiler associated with the book runs code
interpretively. But the game here is for people who can't code to
attack people who can.

Indeed, to continue the silly analogy, Walter wants me to start with
carrier landings rather than simply taking off in a Cessna, and
returning to the airport.
 
S

spinoza1111

I think that's a bit drastic.  There are legitimate uses for a partial
compiler -- say, for a minilanguage where simply running a local evaluator
on the parsed tree is useful.

There are no uses I can think of for a flight manual which only covers
take-off that do not result in a lot of people dying.  A partial compiler
isn't nearly that bad.

Seebach gets it right here.
 
S

spinoza1111

spinoza1111wrote:


A compiler book without code generation and optimization is like
a flight manual that only teaches take-off's.

"Build Your Own .Net Language and Compiler" has a whole chapter on
generating .Net byte code. I've since created software to do this
better for more recent .Net.

It also discusses optimization including constant folding, and the
optimization is implemented in the 26000 line compiler you can
download at Apress.

But the compiler is no F-16, where the F-16 is intended for combat but
is actually used against civilians in Gaza. It's more a Cessna.
 
S

spinoza1111

spinoza1111wrote:



Compiler parsing is a simple mechanical process that is a small
part of compiler implementation. Completing the design and

Do you understand how to do compiler parsing, dear Walter?

Can you explain why recursive descent is easy to implement manually
but bottom up parsing is best left to a generator? You see, I wrote
and published a generator for recursive descent parsing in the Rexx
language, delivering a paper on it in 1991. I realized then that it
may have been overkill since it is somewhat easy using a modern editor
to manufacture recursive descent procedures by hand, and given the
well-known pitfalls of recursive descent (such as evaluating binary
operators at the same level of precedence right to left) the user of
the automated generator may make these types of errors.

On Facebook, I have two Friends, one who teaches high school physics
and the other who teaches university level math. Both complain that
their students haven't learned the basics. I think the same is true of
compsci, and I think it's why people here confuse personal assaults,
saying things are "not true" (without saying what is true), and
undefined C code snippets with knowledge. They never learned the
basics, but have been socialized by the university to use shibboleths
and call the unlearned basics "trivial" in a sufficiently lofty
manner.
implementation of the code generation would both have led
to a complete book and more significantly provided a balanced
view of the process that wouldn't lead to this kind of outrageous

Outrageous? My we are gonna pop a blood vessel, aren't we.
 
S

Seebs

This is not just Keith's opinion, by the way, but the
vandal's own explicitly stated objective.

I am not sure I believe him about that any more than I believe him about
anything else. I do not have information leading me to think that he
is competent to speak as to his own beliefs.

-s
 
E

Eric Sosman

Keith said:
Richard Heathfield said:
In
<72d4c95c-da42-4251-94fe-0ddb1ba28a90@b25g2000prb.googlegroups.com>,
spinoza1111 wrote: [more of the same]
It seems you don't understand "courtesy", either.

This is news? To anyone?

Richard, *please* stop feeding the troll. If the only way you can
manage to resist doing so is to killfile him and actually *stop
reading anything he writes*, even if it happend to be relevant to C,
I urge you to do so.

He is trying to destroy this newsgroup, and you are helping him.

This is not just Keith's opinion, by the way, but the
vandal's own explicitly stated objective.
 
S

spinoza1111

In

spinoza1111wrote:


No, it's true. I don't expect you to understand this.



It seems you don't understand "courtesy", either.

Actually, I do. It's not corporate pseudo-courtesy where everyone is
"nice". The most courteous, and hospitable-to-the-stranger, people on
earth may be the Pathan tribesmen of Afghanistan. If they come upon
you a stranger dying of hunger they will feed you and say my house is
yours. But if you mess with them as did the Russians and as do the
Americans and Europeans today, they fight because they are men, Dickie-
Wad.

You think you can constantly post false claims about your colleagues
here in full view of God and everybody, and enable the worst kind of
"office gossip", and then talk about courtesy and how competent and
humble you are, but we're real tired of your behavior.
 
K

Kaz Kylheku

10. Use of malloc without casting is considered a poor practice (it is an
error in C++). Cast it to suitable type instead.

Actually this recommendation is completely useless, if you don't have
enforcement from the compiler, or some tool like lint.

Without the cast being required due to a mandatory diagnostic, you and your
other programmers will not reliably stick to the above rule.

Even people who believe in the rule will screw up.

I've been trying to switch to the habit of adding the cast, but I find that
I keep forgetting!

So, by itself, this rule has less worth than a rule which says ``it is poor
practice to make some kind of mistake in your use of malloc'', because
it's essentially a rule which says ``it is poor practice to do something that
is often correct, and even considered a good idiom by some C programmers,
some of whom are experts, and for the violation of which there is no diagnostic
support in the standard language''.

But what /is/ poor practice is designing a programming language feature which
allows you to request dangerous conversions without having to provide a written
token that marks the places in the program where these conversions
are happening. You simply use the assignment operator between two expressions,
the same way like you could do in a typeless language between /any/ two
expressions. (E.g. a predecessor of C, like BCPL).

The void and void * types come from C++ which has a better rules for them.
It doesn't have the implicit conversion from void * to any object type,
and C++ doesn't have the silly (void) hack. (Someone should have had the
balls to uproot non-prototype declartions from C back in in 1989: boldly
removing something from a standard doesn't mean compilers can't continue to
support it).

C once had malloc which returned char *. There was nothing wrong with this; it
did not have to change. If anywhere at all, the void * type should have only
been used in the free and realloc functions for passing pointers down.

So, the thing to do is to eliminate the use of the void * type from your C
programs, at least in situations where it will likely be converted to another
type.

I recommend that interfaces which accept a generic pointer-to-anything continue
to be written to accept void * arguments, but when those pointers are returned,
they should be returned as unsigned char *.

Rationale: it is correct and sometimes useful to be able to treat any
object as an array of bytes (unsigned char *). If we don't know what a
pointer points to, but we do know that it points to an object, then
it's okay for that pointer to be a pointer to unsigned char *. We can
safely dereference that pointer to access a byte. Functions that call
malloc only to obtain a block of bytes should not have to do the cast
since any object already /is/ a block of bytes.

If the object is to be used as some other type, even as a char * string, then a
cast will be required. So, you don't need your rule 10: just design the API so
that code won't compile without the cast.
 
E

Eric Sosman

Seebs said:
I am not sure I believe him about that any more than I believe him about
anything else. I do not have information leading me to think that he
is competent to speak as to his own beliefs.

If he's destructive, ignore him.

If he's delusional, ignore him.

Choose whichever response seems fitter.
 
K

Kaz Kylheku

Do you recommend I should rewrite:

int compare_strings(void *a,void *b) {
char *s1 = a;
char *s2 = b;
return strcmp(s1,s2);
}

Firstly, if you're looking to save keystrokes, you are going about it in
a funny way, because the following has the casts /and/ is shorter:

int compare_strings(void *a, void *b)
{
return strcmp((char *) a, (char *) b);
}

If you think the cast is too much work, why don't you think that writing

Absolutely, you should have the casts. You have an unsafe conversion here.
For excellent reasons, the above isn't valid when interpreted as C++.
The problem is, the compiler won't help you if you do want the casts,
but forget them.

I would recommend that the void * type simply be avoided in favor of something
else:

int sort_function(int (*comp)(const unsigned char *, const unsigned char *),
... args);

Now this requires a diagnostic, and you have to put in the casts:

int compare_strings(const unsigned char *a, const unsigned char *b) {
const char *s1 = a;
const char *s2 = b;
return strcmp(s1,s2);
}

The unsigned char * is the best generic pointer-to-any-object in C.
as

int compare_strings(void *a,void *b) {
char *s1 = (char *)a;
char *s2 = (char *)b;
return strcmp(s1,s2);
}

If so, why? If not, why is the void pointer from malloc any different?

The void pointer from malloc is different because you didn't compute it,
malloc did.

You can abuse the comparison function in ways that you cannot abuse the
object from malloc. The object from malloc is always suitably aligned; the only
thing that might be wrong with it is that it might have the wrong size.
(Plus the oddity that if you accidntally request zero bytes, you might get
a null pointer, or might not).

But you can take an array of structures and pass it to qsort with a
comparison function that compares them as something else, such as char *
strings. No diagnostics are required from the program, and there is no way to
restruture the program to obtain diagnostics, without using something other
than qsort.

You can't write a wrapper for sort because qsort doesn't pass through a context
pointer which could be used to chain from a generic comparison function to one
which has a safer type.

If you are using sqort, the only way that the pointer can be just converted to
char * is if you are sorting an array of char arrays, e.g.

char array[][10] = { "foo", "bar", ... };

If you want to sort an array of dynamic strings, i.e. array of char *, you
would have to have:

int compare_fun(const void *le, const void *ri)
{
char **left = (char **) le;
char **right = (char **) ri;
return strcmp(*left, *right);
}

A newbie, or maybe even a not-so-newbie, could easily make mistake here
and just convert the pointers to char *.

The casts don't prevent the mistake, but the casts flag all the places in the
program where dubious manipulation of objects may be taking place.
You can locate these places and review them.

That's a fair trade: you are allowed to do what you want. But you have to
pay for it by writing a little textual token which flags it in a way
that a simple assignment does not.

The cast is like the the ``high voltage'' label on an electric transformer,
or ``poison'' warning on a bottle.

People who argue against casts are essentially arguing that such labels should
be removed. ``Hey, /I/ know what I put in that bottle! If you don't know what
you put in, then you have a process problem that won't be solved by labelling
bottles!''
 
R

Richard Tobin

Walter Banks said:
Compiler parsing is a simple mechanical process that is a small
part of compiler implementation.

What's more, once you've done it, there it is. You probably won't
expend much effort on maintaining and porting it, because once it
works, it works. Given the effort modern compilers spend on
optimising code generation, its efficiency is unlikely to be critical
(30 years ago an author could suggest that the inner loop of a
compiler was typically the character reading of the source file, but
that's certainly not true now). Over the lifetime of a compiler you
will probably target new processors, implement new optimisations,
support new executable formats. But the parser may well stay the
same.

[Of course, that's something of an exaggeration. For example, many
compilers would benefit from some effort expended on parser error
recovery.]

-- Richard
 
W

Walter Banks

spinoza1111 said:
You see, I wrote
and published a generator for recursive descent parsing in the Rexx
language, delivering a paper on it in 1991.

Got a citation it seems to have been missed out of the indexes I checked.
 
S

Seebs

So, the thing to do is to eliminate the use of the void * type from your C
programs, at least in situations where it will likely be converted to another
type.

I don't think so. I think the implicit conversion from (void *) is a
feature, not a bug. It allows us to express the notion of an address,
the contents of which are not known. Say, the return from malloc.

I don't see any point to requiring or performing the cast.

-s
 
S

spinoza1111

I thought you were Nilges. I am missing something or you do talk in
third person for no apparent reason...

I am Nilges. I wrote a compiler book which may have overemphasized the
front end because the back end of a compiler is too machine dependent
to constitute computer science. It was for people with no clue as to
how to parse. But it did discuss elementary optimization and code
generation:

"Constant folding: a surprisingly large number of programs contain
expressions like 32767-2, where a piece of the expression or the
entire expression consists of constants, and it's pretty obvious that
the expression is mathematically and computationally equivalent to
32765. The reason can be clarity of expression, the use of symbolic
constants, or the generation of code automatically".

This passage from my book "Build Your Own .Net Language and Compiler
is followed by a discussion of how constant expressions are evaluated
in the parser unless the option to evaluate them is turned off.

It is then followed by what I call lazy evaluation: in parsing when a
constant operand is discovered that is the unity or zero element of
its "group" (1, 0, false, or true) then we do not bother to generate
code for the binary operation it is input to when that binary
operation has no effect.

All of chapter 9 discusses code generation.
 

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,008
Messages
2,570,268
Members
46,867
Latest member
Lonny Petersen

Latest Threads

Top