A C Adventure: your comments are welcome

B

Ben Bacarisse

<snip long comment>

Apologies to all. I intended to snip the long comment before posting
since I was not going to talk about it. I simply forgot.

<snip>
 
B

Beej Jorgensen

spinoza1111 said:
// ----- Parent segment start index
-------------------------

And you'd do well to make sure the code doesn't wrap when you paste it.
Keeping a 72-column limit is admirable, but it is worse than useless
when it makes the code less readable.

You might also consider using pastebin.com.

This is Usenet, and I'll be the first to admit you're free to post
whatever you want. If you're content with the fact that some people
will ignore your post because of the bad formatting, then there's
nothing to change.

-Beej
 
J

John Bode

[snip]
1.  It seems I cannot include what I want to be a self-referential
struct inside a struct either as the thing itself or as a pointer
because either C or the Navia compiler is basically one-pass. I can't
do this in C Sharp either but can if I change the struct to a class.
So, void pointers raise their pretty little heads.

If lcc doesn't support

struct TYPstring
{
long intSegmentLength;
char * strSegment;
struct TYPstring * usrLeftSegment;
struct TYPstring * usrRightSegment;
};

then lcc is *grievously* broken, which is not bloody likely. What is
far more likely is that you weren't doing what you claim you were
doing.

Note that the following do *not* work:

struct TYPstring
{
long intSegmentLength;
char * strSegment;
TYPstring * usrLeftSegment; /* struct keyword missing */
TYPstring * usrRightSegment; /* C is not C++ */
};

or

struct TYPstring
{
long intSegmentLength;
char * strSegment;
struct TYPstring usrLeftSegment; /* cannot have a struct
reference */
struct TYPstring usrRightSegment; /* an *instance* of
itself */
};

If you tried either of those, lcc would have been correct to reject
it.
 
J

John Bode

[snip]
and this persecution of dissidents and writers like Navia and Schildt

Jacob gets picked on because he's a drama queen. Schildt gets picked
on because he gets (got) basic facts wrong, writes (wrote) abominable
example code that has a 50% chance of compiling and linking, much less
running correctly, and teaches (taught) bad habits.

Granted, it's been over 20 years since the first edition of C: The
Complete Reference, and I'm willing to allow that Schildt may have
actually learned something in the interim, but I'm not going to waste
my money to find out.
 
K

Keith Thompson

Richard Heathfield said:
Phil Carmody said:



There's no point. He wouldn't believe me, and everyone else already
knows.

Please consider applying that logic to everything else you post in
response to spinoza1111's articles.
 
A

Alan Curry

Alan Curry said:


I must admit I hadn't expected anyone to post the source code to an
NNTP client!

Not a very good one, obviously. But I thought: how do you know that there
isn't any evil line-wrapping code in your newsreader? By writing it yourself!
I'm reluctant to do so, but I do have two suggestions, one of which is
almost too tiny to notice, and the other of which is perhaps a little
too *large* for the context. Second one first: have you considered
abstracting connectivity code into its own module? Like I said, it

That main() function ended up being bigger than expected. I was on the edge
of factoring it a couple of times.
would be overkill for a one-off program like this one - but, if you
take the time to do it, it can sit very nicely in a library, saving
you time on future such projects.

The second point is posted inline:




If you initialise, you can avoid the memset.

struct sockaddr_in sa = {0};

Traditional BSD socket code always bzero'd the sockaddrs before filling them
in. I've never really thought about why.
 
S

spinoza1111

spinoza1111said:


And it has taken you over a day to do so, after first attempting to
deny it. Please learn more quickly in future.

You enact, in what could be a space of freedom from corporate
horseshit, the worst features of the nastiest little business office.
This is what masochists, sadists, and othe sexual perverts like to do
in place of dealing with their problems. Are you a sexual pervert?
So do I, actually - but I make sure they don't break on Usenet. Or, if
they do break, I acknowledge that it's my fault, not the reader's
fault.


A single short paragraph is not a mountain. In fact, it's a molehill.
The mountain was caused by your originally trying to wriggle out of
the issue instead of facing up to it and dealing with it - which, to
your credit, you have finally done.

Oh, blow me. I was formatting code beautifully in 1971, using punched
bloody cards. What were you doing in 1971? Having a punch up in a chip
shop in Blackpool, or learning a formerly useful trade such as
metalworking in borstal?
 
S

spinoza1111

<snip>












The usual idiom for a macro whose body is to me almost a statement is:

  #define ERRORHANDLER(strMessage) \
  do { \
      printf("%s\n", (strMessage)); abort(); \
  } while(0)

This accomplishes my intended task of "sealing" the macro body
syntactically and as you point out, it allows the macro caller to call
the macro as if it were normal C. But this virtue could be a defect,
since a macro isn't normal C at all.
Note that there is no ; at the end.  Thus when you later write (as you
do)

  if (CONDITION)
      ERRORHANDLER("Some text");

you get a correct if clause.  You version works in this context but
the ; adds an empty statement that means, amongst other things, that
you can't add and else clause to the if.

When I use my macros, the fact that their names are caps is for me a
heads up, reminding me NOT to terminate the call with a semicolon.
What benefit is this?  It is no shorter, and means the reader must keep
this definition in mind as they read (or keep referring to it).  In
general the even shorter form where one writes:

  ptr = malloc(sizeof *ptr);

or

  ptr_to_lots = malloc(how_many * sizeof *ptr_to_lots);

is better, in my opinion.

Point taken. However, most well-written C code I've seen over the
years macroizes malloc.
Personally, I feel this is enough to put into a function.  C99 has
inlined functions which overcome almost all of the problems with this
sort of macro.
Again, point taken. But I don't see many problems as long as I am
consistent in this style.
 
S

spinoza1111

spinoza1111said:







The tilde is otherwise engaged. $ would have worked (and would
certainly be available). But, as it happens, the comma works out
quite well in the long term.

Saying this doesn't make it true, since the comma is most naturally
used in function calls.
Nor did I claim they were. What I meant was that you've finally
managed to acknowledge the error of your ways, or at least of one
particular way. *That* is a beginning. Long may it continue.

Pompous fool, fool of pomp, dull fool
You are indeed a lord, but a lord of misrule
From your nook-shotten isle of Albion,
Don't pretend to correct this particular American.
Don't Yank my chain, you will have pain,
Don't act this mentor's mentor, the laughter loud
Leaps from the lurker louts in the gallery the crowd.
You lied, you lied, and even Keith Thompson espied
Your lie, your lie, and now you cry.
My code is a thing of beauty and a joy forever
Even before it compiles and even before it works,
And such when it incurs the scorn of jerks,
Only rises above them as they gape beneath
With rotten mouths showing rotten teeth.

I am always civil. A review of your articles illustrates that you are
not. Put your own house in order.

It is true you don't call people asshole, nor do you invite them to
get fucked,
But your type prefers the vicious slur and lie.
I see no reason to stop being civil. I do see a reason, however, for
you to think more carefully before responding to my comments about C
code. I don't make mountains out of molehills. I do point out real
issues, and I will normally give suggestions of how to work round
them. I often skip over minor flaws if they don't seem to merit
attention. (I don't consider diagnosable problems to be "minor
flaws", though.)

Bullshit, dear chap. You made an absurd claim and were called on it.
 
S

spinoza1111

[snip]
and this persecution of dissidents and writers like Navia and Schildt

Jacob gets picked on because he's a drama queen.  

Much of what passes for technical programming comment is actually ugly
sexual and racial politics. You clowns hate Navia and Schildt because
they both did something you cannot and this was write a compiler. You
clowns hate Navia because he's apparently a French guy. And it is to
me paradoxical and sad that you young punks now think that to defend
oneself like a man is to be a drama queen.

You'd be better off buying my book "Build Your Own .Net Language and
Compiler" (Apress 2004).
Schildt gets picked
on because he gets (got) basic facts wrong, writes (wrote) abominable
example code that has a 50% chance of compiling and linking, much less
running correctly, and teaches (taught) bad habits.

His code was meant to run and does run on Windows because that's his
market. He can write English, a language which unlike a mathematical
formalism is subject to multiple interpretations. Therefore, he was
attacked by people without his compiler-writing or English ability.
 
C

Chris McDonald

spinoza1111 said:
...[yet another personal attack snipped]... Are you a sexual pervert?
.....
.....
.....
Oh, blow me. ...[yet more personal grandstanding snipped]....

An unfortunate confluence of thought processes.
 
B

Ben Bacarisse

spinoza1111 said:
When I use my macros, the fact that their names are caps is for me a
heads up, reminding me NOT to terminate the call with a semicolon.

The code you posted had three uses of ERRORHANDLER. Two had a
trailing semicolon. The fact that you can't follow the rule you set
yourself is a string argument in favour of avoiding the need for it.

<snip>
 
J

John Bode

and this persecution of dissidents and writers like Navia and Schildt
Jacob gets picked on because he's a drama queen.  

Much of what passes for technical programming comment is actually ugly
sexual and racial politics. You clowns hate Navia and Schildt because
they both did something you cannot and this was write a compiler. You
clowns hate Navia because he's apparently a French guy. And it is to
me paradoxical and sad that you young punks now think that to defend
oneself like a man is to be a drama queen.

Jacob's smart, and I admire the fact that he has developed a compiler,
but he confuses technical criticisms and disagreements for personal
attacks and, much like you, writes wild diatribes because someone
dared to disagree with a dearly held position of his. Hence the title
"drama queen", which has nothing to do with sexuality or
nationality.
You'd be better off buying my book "Build Your Own .Net Language and
Compiler" (Apress 2004).


His code was meant to run and does run on Windows because that's his
market.

His book wasn't titled "C: The Complete Reference If You're Writing
For DOS (or Windows after 1989)".

His examples had numerous syntax errors and runtime problems that had
nothing to do with platform. Closing a file and then attempting to
write to it is an error, regardless of platform. Dereferencing
invalid or null pointers is an error, regardless of platform. Making
his examples DOS-centric was annoying enough for someone who was
learning C under VAX/VMS, since the student didn't have a clear idea
of where the language ended and the platform-specific extensions
began. But it didn't matter, because the examples were crap anyway. I
didn't know a lot, but I knew basic errors in logic when I saw them.
He can write English, a language which unlike a mathematical
formalism is subject to multiple interpretations. Therefore, he was
attacked by people without his compiler-writing or English ability.

What compiler has Schildt written?
 
N

Nick Keighley

Interesting and perhaps valid point. Yes, I'm going bottom up. But C
provides no other way to represent strings.

the point is you are defining what strings are in your library.
I don't mind a bit of bottom up but heavy use of it leads to
implementation details leaking into your application. I thought
this was what OO was all about. Hell, I thought that was what
Structured Programming was all about! ADTs...


Are you sure in all cases of this? And is my cast a performance hit?

In C the cast is unnecessary as a void* (which malloc() returns)
is automatically converted to any other pointer type. You need the
cast
in C++ but then you don't normally use malloc() in C++.

There is no performance hit. Casts always do little or no work.
And the implicit conversion does the same work as the explicit
(cast) conversion. Modulo a sane compiler.

OK, you and Heathfield concur. I'll consider it.

don't take my word for it check out any good C tutorial or substantial
body of C code. Not only is it standard (right back to K&R e1) but it
is widely used. If you want to moan about C you could moan that -> is
unnecessary.

struct S s;
struct S *ps;

s.field = 1;
ps = &s;
(*ps).field = 2;
ps->field = 2; /* equivalent to previous line */
ps.field = 2; /* illegal */

there is no particular reason why they couldn't have made the last
line
legal and equivalent to the previous 2.


in a function declaration

int f1();
int f2(void);

don't mean the same thing (things are different in C++). f1 takes
an unspecified but fixed number of arguments. f2 takes no arguments.

hence in the definitions

int f1 (int i) {} /* valid */
int f2 (int i) {} /* not valid */

I like my declarations and definitions to look the same
so I put the voids in the definitions.
 
D

Dik T. Winter

> Oh, blow me. I was formatting code beautifully in 1971, using punched
> bloody cards. What were you doing in 1971?

Oh well, at that time I was formatting beautifully in 1971, using punched
bloody tape. So, no line numbers at the end...
 
B

bartc

Nick said:
is widely used. If you want to moan about C you could moan that -> is
unnecessary.

struct S s;
struct S *ps;

s.field = 1;
ps = &s;
(*ps).field = 2;
ps->field = 2; /* equivalent to previous line */
ps.field = 2; /* illegal */

there is no particular reason why they couldn't have made the last
line legal and equivalent to the previous 2.

Lots of reasons. It goes against the grain of the type system for a start:
..field requires a struct on the left, while -> requires a *struct on the
left. You're saying .field can have a ps or *ps on the left, it doesn't
matter! That would be too undisciplined.

Similarly, you'd be saying that (*ps).field is the same as ps.field; somehow
you can dispense with a complete dereference op, and nothing changes! That
can't be right.

It also makes it difficult when looking at ps.field to see at a glance
whether ps is a struct, or a pointer.

And if C was to introduce, say, a sizeof op written as expr.sizeof (which I
know is unlikely), then you would appreciate that ps.sizeof gives the size
of a pointer, and doesn't go dereferencing things so that it gives the size
of the target. (Probably you'd also need ps->sizeof to avoid writing
(*ps).sizeof)

The whole . and -> thing is messy because C chooses to have the dereference
op on the left instead of the right, as in Pascal: ps*.field doesn't look so
bad; you don't need the -> op, and you wouldn't be moaning so much about
sticking an extra * in there. There are a few another advantages too (you
don't have to wonder why * is on the left in *ps but on the right in int*),
but the decision was to place it on the left.
 
N

Nick Keighley

Lots of reasons. It goes against the grain of the type system for a start:
.field requires a struct on the left, while -> requires a *struct on the
left. You're saying .field can have a ps or *ps on the left, it doesn't
matter! That would be too undisciplined.

Similarly, you'd be saying that (*ps).field is the same as ps.field; somehow
you can dispense with a complete dereference op, and nothing changes! That
can't be right.

It also makes it difficult when looking at ps.field to see at a glance
whether ps is a struct, or a pointer.

And if C was to introduce, say, a sizeof op written as expr.sizeof (which I
know is unlikely), then you would appreciate that ps.sizeof gives the size
of a pointer, and doesn't go dereferencing things so that it gives the size
of the target. (Probably you'd also need ps->sizeof to avoid writing
(*ps).sizeof)

The whole . and -> thing is messy because C chooses to have the dereference
op on the left instead of the right, as in Pascal: ps*.field doesn't look so
bad; you don't need the -> op, and you wouldn't be moaning so much about
sticking an extra * in there. There are a few another advantages too (you
don't have to wonder why * is on the left in *ps but on the right in int*),
but the decision was to place it on the left.

excellent. A pleasure to be refuted
 
N

Nick Keighley

Lots of reasons. It goes against the grain of the type system for a start:
.field requires a struct on the left, while -> requires a *struct on the
left. You're saying .field can have a ps or *ps on the left, it doesn't
matter! That would be too undisciplined.

It would be really bad if C were to reuse an operator for more
than one purpose
Similarly, you'd be saying that (*ps).field is the same as ps.field; somehow
you can dispense with a complete dereference op, and nothing changes! That
can't be right.

It also makes it difficult when looking at ps.field to see at a glance
whether ps is a struct, or a pointer.

the declaration should be nearby
 

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

No members online now.

Forum statistics

Threads
473,951
Messages
2,570,113
Members
46,698
Latest member
alexxx

Latest Threads

Top