Reading a string of unknown size

K

Keith Thompson

CBFalconer said:
Keith said:
Santosh Nayak said:
I suggest that one or both of the [Ss]antosh's currently posting
here consider using their full name to avoid confusion. (Neither
of them, of course, is obligated to follow my advice.)

Sounds Logical !

Thanks. If I have this straight, you've been signing yourself as
"Santosh", and you started posting here recently; the other Santosh
has been signing himself as "santosh" and has been posting here for
some time. Is that right?

I think it's the other way around. The 'good' santosh has been
using lower case s.

That's what I said. Assuming that "the 'good' santosh" refers to
the one who's been posting here for a long time (I'm not going to
make any value judgements), he's the one who has been posting with a
lower case s; Santosh Nayak is the relative newcomer, and he's been
posting with an upper case S. (And Santosh Nayak confirmed this,
in a followup that you probably didn't see before posting yours.)

So, "santosh" (no last name, lower case s) has been posting here for a
long time, and "Santosh Nayak" is a relative newcomer, who briefly
posted as "Santosh".
 
R

Richard Tobin

And, of course, the real difference is that the first compiles straight
in C++, and the second is just an error. I have found that in general
the C++ optimizers and warnings are better for the C++ mode of my
compilers than the C mode.
[/QUOTE]
Fortran compilers are usually even better than that. Obviously
you should write your C code so that it compiles with Fortran compilers.

Or use IBM's PL/1 checkout compiler. It will give you lots of
warnings, but will probably translate your code into PL/1 as a bonus.

-- Richard
 
B

Barry Schwarz

santosh wrote:
Can u please further explain the following statement....

"Don't cast return value of malloc() in C. It can hide the
non-inclusion
of it's prototype, (by way of failure to include stdlib.h), and, on
some implementations, can result in nasty crashes during runtime."

I am unable to understand the intricacies of the above statement.

Under the C89 standard, an undeclared function is presumed to return
an int. It is entirely possible for an int to be returned by a
function using a different method than that used to return a pointer.

If there is no prototype in scope for malloc, but there is a cast,
then the usual warning about converting from an int to a pointer is
suppressed because the cast says to the compiler "I know what I'm
doing". The code that is generated will convert the supposed int to a
pointer. Since malloc really returned a pointer, the generated code
is processing a non-existent int.

Furthermore, malloc requires a size_t argument. There is an awful lot
of code where the argument expression has type int. If a prototype is
in scope, the argument will be converted automatically. If not, the
compiler will happily generate an int and pass it to malloc. If
size_t is not an (unsigned) int but a larger type, who knows what data
malloc will consider as the argument.

Both cases are examples of undefined behavior which, according to
Murphy's law, will appear to work until it is most damaging not to
(e.g., demonstration in front of very important customer).

On the other had, if you omit the cast, the diagnostic regarding the
conversion of an implied int to a pointer should provide enough
incentive to include stdlib.h which will automatically eliminate the
possibility of either problem occurring.

Since there is a well-defined implied conversion between void* and any
other object pointer type in either direction, the cast gains you
nothing but prevents the compiler from helping you in the case you
forgot the include the header. What some might call a lose/no-win
situation.

The oft recommended position in clc is cast only when you really know
why your are casting.


Remove del for email
 
W

websnarf

Eric said:
(Macros cure errors? News to me ...)

I'm sure a lot of obvious things are news to you. What's not news to
me is that you would take a narrow statement I've made and
intentionally pretend I said something more general.
The principal advantage of the recommended form is that a
visual inspection of the line *in isolation* tells you whether
it's correct or incorrect.

Which means what, in terms of coding safety? You are trading compiler
enforced type checking for manual based safety checking. You don't see
the inherent flaw in this? In your world people get blamed for
mistakes that in my world cannot even be made.
[...] If the l.h.s. agrees with the sizeof
operand, the allocation is correct (unless <var> is a float or
an int or some other non-pointer thing, in which case the
compiler will squawk anyhow).

You do not need to go hunting for the declaration of <var>,

My compiler tells me the two types that are in conflict at the
diagnostic line (as does yours, probably) so I don't need to "hunt" for
anything with my solution either.
nor do you need to rummage around for the definition of some
macro and try to figure out its expansion. You can verify the
correctness of the code with a "local" inspection, without
digging through a pile of headers, hoping you've found the
right version and haven't been fooled by a morass of conditional
compilation.

The risk of error is simply not balanced by this. You can name your
macro genericArrayAlloc(,) and I don't think people will worry too much
about how the macro expands.

If your code is hundreds of thousands of lines, or if its been
substantially written by someone else, then manual inspection of all
your code is not a feasible option. Wherever possible, the tools and
compilers themselves should be enlisted to find as many "obvious once
you look at it" kinds of bugs automatically.
Why not? I don't see any advantage in writing such a macro,
but if you chose to do so the expression it generated would be
perfectly good as an argument to function.

It requires an additional variable declaration that may be superfluous.
Hiding the "=" operator or anything as complex in macros is the kind
of thing that eventually leads to problems.
(Have you interchanged "first" and "second" here?)
(Yes)

It doesn't seem to me that one's C style should be twisted
in deference to the practices of C++, or of Java, or of COBOL.

It isn't a matter of style. Its a matter of gaining access to better
tools. My C compilers simply don't emit a comparable number of
diagnostics, nor the quality of code that my C++ compilers do (even
when they are made by the very same vendor, packaged in the very same
tool.)

Making your C code compilable in C++ is a net gain in productivity, and
leads to a drammatic improvement in correctness, and a measurable
improvement in object code performance. Java and COBOL are
non-sequitor in this discussion.
 
W

websnarf

Chris said:
Fortran compilers are usually even better than that.

Uhhh ... no they are not. Fortran compilers only compare favorably to
some C compilers in very narrow situations where the C compiler is
unable to prove that some pointers are non-aliasing ("restrict" was
added to C99 to eliminate this scenario completely). The real
challenge is to implement x << y in Fortran so that its no worse than 4
times slower than the comparable C output.

The point is, of course, that you almost certainly already know this
....
[...] Obviously
you should write your C code so that it compiles with Fortran compilers.

.... which makes this at best a poor attempt at sarcasm, but more likely
an intentional deception.
 
K

Keith Thompson

Chris Torek wrote: [...]
[...] Obviously
you should write your C code so that it compiles with Fortran compilers.

... which makes this at best a poor attempt at sarcasm, but more likely
an intentional deception.

Chris's comment was obviously sarcastic (I won't comment on whether it
was a "poor attempt"). If you seriously believe that Chris Torek is
intentionally trying to deceive people into believing that programmers
should write C code so it compiles with Fortran compilers, you have a
*severe* misunderstanding.
 
W

websnarf

Richard said:
(e-mail address removed) said:

It merely hides one.


No, there is an even bigger risk - cargo cult programming, which is what
most people are doing when they cast malloc.

Uhh ... ok, but which has worse outcome? Superfluous structure that
your compiler is going to strip out of the object code anyways has no
negative impact on correctness or performance. Messing up a void *
pointer will cause truly arbitrary action. The two are not comparable
by outcome.
[...] It can hide the non-inclusion of it's prototype,

On *SOME* older generation compilers. No modern compiler fails to give
a warning about this regardless of the cast.

So if anyone comes up with a counter-example, you can simply claim that it's
not a "modern" compiler. ("True Scotsman" argument.)

For development? Are you going to use a digital watch to run your
compiler? You can demand minimum standards for your development
platform -- and numerous free compilers exist that behave as I suggest.
[...] Furthermore, do not
forget that some organisations are remarkably conservative, and will not
change software that they know to work - especially if that software is
mission-critical, as compilers easily can be.

Right -- but those same organizations are unlikely to be developing
lots of new code anyways. I don't look to such organizations to
leadership on how I should program. I only suffer their nonsense if
they are handing me a paycheck.
[...] (by way of failure to include stdlib.h), and, on
some implementations, can result in nasty crashes during runtime.

Since sizeof(char) is by definition 1, you can omit that and instead do
'2 * sizeof *str'. This has the advantage of becoming automatically
updated when you later on happen to change the type of *str.

If you want automatic type safety you should do this:

#define safeMallocStr(p,n,type) do { (p) = (type *) malloc
((n)*sizeof (type)); } while (0);

That doesn't look very type-safe to me.

void *p;
safeMallocStr(p, n, void); /* requires a diagnostic */

My compiler barfs on sizeof(void). So the error is caught.
void *q;
safeMallocStr(q, n, char);
int *r = q; /* so much for type safety */

That's ridiculous. Use of void * is never type safe. Using the
non-casting style of malloc usage doesn't change the above scenario in
any relevant way. Ironically, the correct solution is to use a C++
compiler which would spit errors at you for the last line.
Why not just remove the mismatch risk completely?

What risk are you talking about? Outside of gratuitous use of void *
pointers (which is tantamount to using gets() in "controlled
environments") there is no risk.
Wrong.

T *p;

p = malloc(n * sizeof *p);

Now change p's type to U *. The malloc is still correct, and does not need
an extra, potentially error-prone, edit to a spurious macro call.

The macro is potentially error-prone, but mismatching the variable and
the thing you are taking sizeof is not error-prone? Fiirst of all, you
have not explained how the macro is error prone, while the above is so
obviously susceptable to cut-and-paste errors.
 
E

Eric Sosman

Eric said:
(e-mail address removed) wrote On 11/28/06 14:54,:
[...]
Well, this still has the potential for cut and paste errors unless you
macrofy the whole line. If you don't macrofy, then you risk error no
matter what.

(Macros cure errors? News to me ...)

I'm sure a lot of obvious things are news to you.

I'm sure you're right, which means I must have missed
something obvious.
Which means what, in terms of coding safety? You are trading compiler
enforced type checking for manual based safety checking. You don't see
the inherent flaw in this? In your world people get blamed for
mistakes that in my world cannot even be made.

No, I'm considering the poor sod who's trying to track down
a bug in a big hairy intertwined mess of code. If he's reading
along and he sees the Recommended Form, he can tell at once that
it's correct and not the cause of his problem (barring a mis-
computation of the number of items to be allocated, which he
needs to check in either formulation). He is not distracted by
the need to go haring off to other parts of the code base to find
out what the Dickens this macro is, or whether its customary
definition has been overridden by some "clever" use of #ifdef in
a well-concealed header file. (If you haven't encountered such
things, you haven't been around long enough.) He can read, verify,
and move along, all without scrolling the screen. That means his
attention is not diverted away from whatever the bug is; blind
alleys are eliminated without strolling down them.
The risk of error is simply not balanced by this. You can name your
macro genericArrayAlloc(,) and I don't think people will worry too much
about how the macro expands.

If they don't, they should. Quickly, now: From the evidence
at hand, which argument is the type and which is the count? Or
is one of the arguments supposed to be the l.h.s. variable name
and not a type name at all? You can stare all day at the point
of invocation and not know what the macro expands to -- and you
can hunt all day through mazes of header files to find half a
dozen different conflicting definitions of the macro, and waste
time trying to figure out which is in force at the point of interest.
If your code is hundreds of thousands of lines, or if its been
substantially written by someone else, then manual inspection of all
your code is not a feasible option. Wherever possible, the tools and
compilers themselves should be enlisted to find as many "obvious once
you look at it" kinds of bugs automatically.

The largest program I have worked on myself was only about three
million lines, roughly 2.5 million of C and 0.5 million of Lisp.
It was written and rewritten and re-rewritten over a period of about
fifteen years by a programming team that started as half-a-dozen
crazy zealots and grew (irregularly) to perhaps ninety or a hundred
people. I was one of them for eleven years, and have (I think) the
bare beginnings of an idea of what it must be like to work on a
big software project. (No, three million lines isn't "big" by any
standard. All I'm saying is that it's "big enough" to exceed a
human's ability for direct comprehension and to require the use of
conventions and suchlike formalisms as aids to understanding.)

And in light of what I've experienced, I stand by my opinion.
It requires an additional variable declaration that may be superfluous.
Hiding the "=" operator or anything as complex in macros is the kind
of thing that eventually leads to problems.

Straw man: It was your decision, not mine, to hide an assignment
inside the macro. You are criticizing your own macro, not the form
it distorts.
> Making your C code compilable in C++ is a net gain in productivity,
> and leads to a drammatic improvement in correctness, and a measurable
> improvement in object code performance. Java and COBOL are
> non-sequitor in this discussion.

"Sequitur." It's Latin, like C an old-fashioned language. If
you prefer Italian and C++ by all means speak them, but don't try
to give advice to the classicists.
 
W

websnarf

Keith said:
Chris Torek wrote: [...]
[...] Obviously
you should write your C code so that it compiles with Fortran compilers.

... which makes this at best a poor attempt at sarcasm, but more likely
an intentional deception.

Chris's comment was obviously sarcastic (I won't comment on whether it
was a "poor attempt"). If you seriously believe that Chris Torek is
intentionally trying to deceive people into believing that programmers
should write C code so it compiles with Fortran compilers, you have a
*severe* misunderstanding.

Typical shallow point of view on your part.

He's deceiving people by 1) intentionally reading that my argument is
that you should make your C code work in languages that might output
faster code (clearly I am picking C++ for the obvious reasons) and 2)
he's propogating the idea that Fortran is faster than C as a blanket
statement (this isn't true).

For sarcasm to be effective, you normally fairly represent what the
opposing idea (not done here) is and then show it at its extreme. He
starts by encoding two deceptions (which is a very typical propogandist
trick; if you unravel one deception, you may still fail to unwrap the
other) then applies his sarcasm in this case as a means of
misdirection. Then the sheep just ignore the deceptions and assess it
for its sarcastic value.

People who watch Fox News critically will recognize this as a very
standard trick they engage in all the time (host: "Do the democracts
support terrorism by suggesting we withdraw our troops?" fake-liberal:
"No! We are not cut and runners").

The only question here: Is Chris a liar or is he stupid? I don't think
he's stupid.
 
R

Richard Heathfield

(e-mail address removed) said:

he's propogating the idea that Fortran is faster than C as a blanket
statement (this isn't true).

He said no such thing.
The only question here: Is Chris a liar or is he stupid? I don't think
he's stupid.

Nor is he a liar. And to ask the only *other* question remaining, I don't
think you're a liar either. So that's settled, then.
 
R

Richard Heathfield

(e-mail address removed) said:
Uhh ... ok, but which has worse outcome? Superfluous structure that
your compiler is going to strip out of the object code anyways has no
negative impact on correctness or performance.

If it's superfluous (your word, not mine, but I agree that it is appropriate
here), you might as well leave it out.
Messing up a void *
pointer will cause truly arbitrary action. The two are not comparable
by outcome.

Have you ever tried *not* messing up a void * pointer? I have. It works just
fine.
[...] It can hide the non-inclusion of it's prototype,

On *SOME* older generation compilers. No modern compiler fails to give
a warning about this regardless of the cast.

So if anyone comes up with a counter-example, you can simply claim that
it's not a "modern" compiler. ("True Scotsman" argument.)

For development?

Sure. Just because an implementation doesn't give one particular diagnostic
message that Paul Hsieh thinks it should, that doesn't mean it's a Bad
Compiler.
Are you going to use a digital watch to run your
compiler?

Is it your contention, then, that only compilers that run on digital watches
do not issue such warnings?
You can demand minimum standards for your development
platform -- and numerous free compilers exist that behave as I suggest.

Paul Hsieh's suggestions on compiler behaviour are non-normative.
[...] Furthermore, do not
forget that some organisations are remarkably conservative, and will not
change software that they know to work - especially if that software is
mission-critical, as compilers easily can be.

Right -- but those same organizations are unlikely to be developing
lots of new code anyways.

That has not been true of several such organisations of which I have
personal experience.
I don't look to such organizations to
leadership on how I should program. I only suffer their nonsense if
they are handing me a paycheck.
Bingo.


My compiler barfs on sizeof(void). So the error is caught.

Yes, but you now have your maintenance programmer wondering why the heck he
can't put void there - it worked all right for char, so why not void? He
has to dig out the macro to find out, which means pushing his context and
digging out the header. What a waste of time.

That's ridiculous.

Yes, but then it uses a ridiculous macro.
Use of void * is never type safe.

And it's not only legal but even idiomatic C. So trying to make C type safe
is a bit like trying to make Ook! object-oriented.
Using the
non-casting style of malloc usage doesn't change the above scenario in
any relevant way.

I agree entirely, but my point was only that your macro doesn't magically
introduce type safety into a language that I prefer to think of as "type
aware". To some people, type safety is a straitjacket.
Ironically, the correct solution is to use a C++
compiler which would spit errors at you for the last line.

Ironically, by introducing C++ into this argument you just explained why
your suggestions about C should be treated with a pinch of salt.
The macro is potentially error-prone,

Yes. The macro needs to be told the type, and you can get the type *wrong*.

p = malloc(n * sizeof *p); does not need to be told the type, so you can't
get the type wrong.
but mismatching the variable and
the thing you are taking sizeof is not error-prone?

There is no such mismatch in the canonical form.
 
W

websnarf

Richard said:
(e-mail address removed) said:


He said no such thing.

Well this is what he said: "Fortran compilers are usually even better
than that." (responding my statement about compiler optimizers and
warnings). You see his *attempt* at sarcasm doesn't work unless he is
able to establish this premise. Otherwise, his statement doesn't make
any sense at all.
Nor is he a liar.

Ok, he's made two gross mistakes in premise. But he clearly has a lot
of experience, and at least some skill as far as I can tell. Neither
mistake really makes sense in light of where you would expect his level
to be at. Well, ok maybe he was drunk or something -- you could argue
that's a form of temporary stupidity I guess.

But ignoring the more bizarre possibilities, what are we left with?
[...] And to ask the only *other* question remaining, I don't
think you're a liar either.

Ok, so upon what do you base this question?
[...] So that's settled, then.

Right, because that's how usenet discussions are always settled.
 
R

Richard Heathfield

(e-mail address removed) said:

Ok, [Chris Torek has] made two gross mistakes in premise. But he
clearly has a lot of experience, and at least some skill as far as I can
tell.

As far as I can tell, he has more of both than you do. And that's likely to
be the perception amongst others here too. That doesn't mean he's
infallible. But if you and he disagree over something, common sense and
experience will lead me to assume that he's right and you're wrong, unless
you can come up with some extraordinarily convincing counter-evidence. So
far, you have not done so.
Neither
mistake really makes sense in light of where you would expect his level
to be at. Well, ok maybe he was drunk or something -- you could argue
that's a form of temporary stupidity I guess.

But ignoring the more bizarre possibilities, what are we left with?

The possibility that he's right and you're either wrong or misinterpreting
what he's said.
[...] And to ask the only *other* question remaining, I don't
think you're a liar either.

Ok, so upon what do you base this question?

You said: "The only question here: Is Chris a liar or is he stupid? I don't
think he's stupid." In so doing, you called Chris's integrity into
question. And so either you were stupid enough to believe that Chris was
lying or you were lying because you knew he wasn't but were trying to
deceive people into believing he was. And I don't think you're a liar.

Attacking generous-hearted and much-loved old-timer experts like Chris Torek
is a risky strategy in comp.lang.c. If he's actually *wrong* about
something (and apparently there was a time back in 1974...), then sure,
let's put it right. But "either you're stupid or you're lying" is an
attack, plain and simple. You might turn those guns on a troll without
anyone batting an eyelid - but Chris Torek? Forget it.

[...] So that's settled, then.

Right, because that's how usenet discussions are always settled.

No, sometimes logic prevails. It just doesn't happen very often.
 
W

websnarf

Eric said:
Eric said:
(e-mail address removed) wrote On 11/28/06 14:54,:
[...]
Well, this still has the potential for cut and paste errors unless you
macrofy the whole line. If you don't macrofy, then you risk error no
matter what.

(Macros cure errors? News to me ...)

I'm sure a lot of obvious things are news to you.

I'm sure you're right, which means I must have missed
something obvious.

Ok, boys and girls, can you spot two errors in logic in a row by Mr.
Sosman in these quotes above?
No, I'm considering the poor sod who's trying to track down
a bug in a big hairy intertwined mess of code.

Ok, but you are just injecting your paranoia into the equation here, as
a poor cover for this groundless idea.
[...] If he's reading
along and he sees the Recommended Form,

Of course, capital letters -- I guess that must make it an athoritative
dictum that cannot be questioned.
[...] he can tell at once that
it's correct and not the cause of his problem (barring a mis-
computation of the number of items to be allocated, which he
needs to check in either formulation).

This is only relevant if you can assume that he can read every line of
code in the program. A silent mistmatch on types via void * will not
rear its head in obvious ways. You have to mechanically prevent it
otherwise it will just lead to problems at some realized constant rate.
[...] He is not distracted by
the need to go haring off to other parts of the code base to find
out what the Dickens this macro is, or whether its customary
definition has been overridden by some "clever" use of #ifdef in
a well-concealed header file. (If you haven't encountered such
things, you haven't been around long enough.)

Debugging is of arbitrary complexity. There's little you can do about
that. Blanket conceptions like "don't use macros" are basically no
help, especially when you can actually use macros to increase safety.
[...] He can read, verify,
and move along, all without scrolling the screen.

Yes but under your premise he has to repeat this a million times with
perfect precision otherwise this process is not really any good to
anyone.
[...] That means his
attention is not diverted away from whatever the bug is; blind
alleys are eliminated without strolling down them.

You are mixing two things up here. You are trying to decrease the cost
of debugging (which in reality you really aren't) at the expense of
up-front safety. Its always easier and faster to not have to deal with
bugs than it is to debug them.
If they don't, they should. Quickly, now: From the evidence
at hand, which argument is the type and which is the count?

The compiler compiled it. (I came up with this answer about in 0.2
seconds. Quick enough for you?) So the type and the count will
correspond to whatever correctly compiled.

Now just as quicky: if you redefined "sizeof" can the compiler think
the argument of malloc(n*sizeof*p) is a multiplication of 3 values?
[...] Or
is one of the arguments supposed to be the l.h.s. variable name
and not a type name at all? You can stare all day at the point
of invocation and not know what the macro expands to -- and you
can hunt all day through mazes of header files to find half a
dozen different conflicting definitions of the macro, and waste
time trying to figure out which is in force at the point of interest.

You could, or you could step through it with a debugger, see that its
correct and move on.
The largest program I have worked on myself was only about three
million lines, roughly 2.5 million of C and 0.5 million of Lisp.
It was written and rewritten and re-rewritten over a period of about
fifteen years by a programming team that started as half-a-dozen
crazy zealots and grew (irregularly) to perhaps ninety or a hundred
people. I was one of them for eleven years, and have (I think) the
bare beginnings of an idea of what it must be like to work on a
big software project. (No, three million lines isn't "big" by any
standard. All I'm saying is that it's "big enough" to exceed a
human's ability for direct comprehension and to require the use of
conventions and suchlike formalisms as aids to understanding.)

I don't see this as testimony in favor of your approach. With a light
macro, the compiler will keep you in check. Without it, you have only
your wits and a hope that your coding convention be followed. My
experience is that in large enough groups, coding conventions erode
over time.
And in light of what I've experienced, I stand by my opinion.

Right. Most of the rest of the industry stands by completely other
opinions. Entire programming languages we created because of these
sorts of inanities in C.
Straw man: It was your decision, not mine, to hide an assignment
inside the macro. You are criticizing your own macro, not the form
it distorts.

Well but you are proposing not using a macro at all, and I am not going
to address the safety of doing that other than to say that it becomes a
cut and paste silent error magnet. So I'm pointing out that the
no-cast method is going to end up sub-optimal no matter what you do.
 
R

Richard Heathfield

(e-mail address removed) said:

Now just as quicky: if you redefined "sizeof" can the compiler think
the argument of malloc(n*sizeof*p) is a multiplication of 3 values?

If you redefined sizeof you wouldn't be programming in C any more. When you
have a sensible argument, wake me up.
 
W

websnarf

Richard said:
(e-mail address removed) said:
Ok, [Chris Torek has] made two gross mistakes in premise. But he
clearly has a lot of experience, and at least some skill as far as I can
tell.

As far as I can tell, he has more of both than you do. And that's likely to
be the perception amongst others here too. That doesn't mean he's
infallible. But if you and he disagree over something, common sense and
experience will lead me to assume that he's right and you're wrong, unless
you can come up with some extraordinarily convincing counter-evidence. So
far, you have not done so.

Given a previous discussion the two of us were in, I have to resist
making the ridiculously obvious retort at this point. Let me put it in
the most polite way as possible -- do you really think that your
personal deference to him is somehow supposed to mean something to me?
If it helps, let me tell you that I am a naturally anti-authoritarian
person. I strongly feel that pedistals are meant to be knocked over
(they serve no other real purpose).
The possibility that he's right and you're either wrong or misinterpreting
what he's said.

Uh ... he said Fortran was better than C (at optimization and/or
diagnostics). No matter how much you delete this quote, he still said
it. If he can make a strong case for the diagnostics, then I will
concede that he just wasn't being clear (but bizarrely intentionally
so). As for the optimizations, he's barking up the wrong tree if he
wants to try to present that case to me.

Ok, then he implied that I said you should consider using a C++
compiler to compile your C code, solely because it has better
optimizations and diagnostics. Obviously I only suggest this because
its just so easy to make your code both C and C++ compatible, so there
is a lot up side benefit (better optimized, better diagnostics) from
making your code C++ compatible with relatively little cost. Even if
Fortran were faster on average (again, it is not, and everyone knows
this) I am in no way implying that you should try to make a C/Fortran
polyglot or switch to Fortran or anything like that.

I'm trying to figure out what I'm missinterpreting or am getting wrong
in all of this. I just can't see it. Certainly your evidence-free
claims about this misinterpretation is of no help.
[...] And to ask the only *other* question remaining, I don't
think you're a liar either.

Ok, so upon what do you base this question?

You said: "The only question here: Is Chris a liar or is he stupid? I don't
think he's stupid."

That is a conclusion after some build-up yes. I obviously didn't say
that in isolation.
[...] In so doing, you called Chris's integrity into
question.

Ok, well he's publically twisted my words and made a sarcastic remark
in order make the point that I am either advocating something ludicrast
(making your code into polygots) or have made some kind of error in
reasoning that ultimately leads to that. Chris ordinarily commands
some sort of respect in this group, so I wonder who is calling who's
integrity into question here?
[...] And so either you were stupid enough to believe that Chris was
lying or you were lying because you knew he wasn't but were trying to
deceive people into believing he was. And I don't think you're a liar.

Excuse me? The *EFFECT* of what he wrote *DOES* deceive. This is not
credibly in dispute. He claims I am saying and implying things I
clearly am not, and has added a clearly mistaken claim to this. He has
put his name to these erroneous words. When this happens, the ordinary
options are 1) malice, 2) error, 3) incompetence. I've ruled out <2)
error> simply because his track records suggests he couldn't make two
simultaneous errors of that kind at once.

I call BS on the both of you.
 
W

websnarf

Richard said:
(e-mail address removed) said:

If it's superfluous (your word, not mine, but I agree that it is appropriate
here), you might as well leave it out.

You mean like you should never comment your code because comments are
superfluous? (Certainly, their value is at best subjective.)
Sometimes redundancy is useful -- this is the lesson of structured
programming.
Have you ever tried *not* messing up a void * pointer? I have. It works just
fine.

Sure. Self-modifying code works fine too. You know, I've written my
own fully functional co-routine library that only works in the
"register mode" of WATCOM C/C++ and a full multithreading library that
only works in DOS. I've written a compile-on-the-fly image scalar that
supports three different compilers and targets x86 CPUs that support
MMX. But taking a step back, it occurrs to me that "it works fine" is
a fairly low standard for writing code.

On the counter point, have you ever tried to debug a messed up type
coercion hidden by a void *? The real problem with it is that you
don't even realize that's what's gone wrong until you get deeply into
debugging in. And the debugger will typically be far less helpful than
you wished.
[...] It can hide the non-inclusion of it's prototype,

On *SOME* older generation compilers. No modern compiler fails to give
a warning about this regardless of the cast.

So if anyone comes up with a counter-example, you can simply claim that
it's not a "modern" compiler. ("True Scotsman" argument.)

For development?

Sure. Just because an implementation doesn't give one particular diagnostic
message that Paul Hsieh thinks it should, that doesn't mean it's a Bad
Compiler.

Right ... but we're several posts into this, and you couldn't even come
up with one? Does the Diep compiler do this? Some UNIX cc that I have
not encountered? Green-Hills compiler? I'm just listing the ones I
know about, but have never used to verify whether or not they warn you
about missing prototypes.
Is it your contention, then, that only compilers that run on digital watches
do not issue such warnings?

Well, old compilers don't issue the warning, because it used to be
considered valid C code without question. I've already implicitely
conceded this.
You can demand minimum standards for your development
platform -- and numerous free compilers exist that behave as I suggest.

Paul Hsieh's suggestions on compiler behaviour are non-normative.
[...] Furthermore, do not
forget that some organisations are remarkably conservative, and will not
change software that they know to work - especially if that software is
mission-critical, as compilers easily can be.

Right -- but those same organizations are unlikely to be developing
lots of new code anyways.

That has not been true of several such organisations of which I have
personal experience.
I don't look to such organizations to
leadership on how I should program. I only suffer their nonsense if
they are handing me a paycheck.
Bingo.


My compiler barfs on sizeof(void). So the error is caught.

Yes, but you now have your maintenance programmer wondering why the heck he
can't put void there - it worked all right for char, so why not void? He
has to dig out the macro to find out, which means pushing his context and
digging out the header. What a waste of time.

What? void is not a thing. If a maintenance programmer wants to sort
a 0-sized list, or return auto-declared arrays, he can do that too.
The difference is that stuffing void in there is completely
unmotivated, and the *compiler* tells you about the error. You have a
strange notion of what the true cost of development is.
That's ridiculous.

Yes, but then it uses a ridiculous macro.
Use of void * is never type safe.

And it's not only legal but even idiomatic C.
s/m/t/

[...] So trying to make C type safe is a bit like
trying to make Ook! object-oriented.

Interesting observation. If you intersect C and C++ what are you left
with? Its like its C without some of the marginal constructs and it
has the type safety of C++.
I agree entirely, but my point was only that your macro doesn't magically
introduce type safety into a language that I prefer to think of as "type
aware". To some people, type safety is a straitjacket.

Well to some people type safety is free automated assistance.
Ironically, by introducing C++ into this argument you just explained why
your suggestions about C should be treated with a pinch of salt.

Do I smell a fundamentalist ideology?
Yes. The macro needs to be told the type, and you can get the type *wrong*.

But the compiler won't allow it to compile. Compile time errors are
basically zero cost. You may perceive the cost of development to be
"typing code in". I lean towards the idea that safety and debugging
costs more than typing code in, and debugging is far more costly than
up-front safety.
p = malloc(n * sizeof *p); does not need to be told the type, so you can't
get the type wrong.


There is no such mismatch in the canonical form.

I don't know what you are talking about. You cut and paste, you change
the target variable and miss the sizeof variable. Ok, you've just
introduced a silent error, that's many hours of debugging waiting to
happen. In my case, you change a variable declaration, and the
compiler then lists, all the places where you have created a type
mismatch. A few minutes maybe, even if you have to write an awk
script. As soon as you make it compile worthy, you are set.
 
R

Richard Heathfield

(e-mail address removed) said:
You mean like you should never comment your code because comments are
superfluous?

I don't agree that comments are superfluous. *You* said the structure was
superfluous, and "superfluous" means "redundant, unnecessary" (look in a
dictionary if you don't believe me).
(Certainly, their value is at best subjective.)
Sometimes redundancy is useful -- this is the lesson of structured
programming.

If it's useful, how can it be redundant?
Sure. Self-modifying code works fine too.

In my experience, such code nails you pretty firmly to a particular platform
(or group of closely-related platforms).

But taking a step back, it occurrs to me that "it works fine" is
a fairly low standard for writing code.

Taking a step forward again, "it works fine" is a fabulous *baseline* for
writing code. For example, fopen works fine, and I use it quite happily,
without worrying that my code is somehow of a low standard just because it
uses something that works fine. Using void pointers correctly does not
imply fragile code. Using void pointers incorrectly is a losing strategy.
But so is using casts incorrectly. So is using fopen incorrectly. So is
using *anything* incorrectly.
On the counter point, have you ever tried to debug a messed up type
coercion hidden by a void *?

Yes - in fact I've almost certainly done so right here in comp.lang.c. And
I've debugged screwed-up macro calls, too. So?
The real problem with it is that you
don't even realize that's what's gone wrong until you get deeply into
debugging in. And the debugger will typically be far less helpful than
you wished.

"Think first, compute later" is always a good plan. I generally don't bother
too much with debuggers nowadays. They are occasional ports in a storm,
that's all.

[...] It can hide the non-inclusion of it's prototype,

On *SOME* older generation compilers. No modern compiler fails to
give a warning about this regardless of the cast.

So if anyone comes up with a counter-example, you can simply claim
that it's not a "modern" compiler. ("True Scotsman" argument.)

For development?

Sure. Just because an implementation doesn't give one particular
diagnostic message that Paul Hsieh thinks it should, that doesn't mean
it's a Bad Compiler.

Right ... but we're several posts into this, and you couldn't even come
up with one?

Why bother? The diagnostic message is not required by the Standard, so it
makes no sense to me to insist to compiler-writers that they provide it. In
general, I use the compiler I'm given when on client sites. If I were to
say to a client, "Paul Hsieh suggests we use a different compiler to the
one you've been using quite happily for this whole project and many others
before, because this one doesn't diagnose <foo>, which it isn't required to
by the Standard", he'd laugh in my face, and rightly so.


"idiotatic"? Okay, let's assume you mean "idiotic". It is your right to hold
that opinion, but your saying that use of void * is idiotic doesn't make it
so.
[...] So trying to make C type safe is a bit like
trying to make Ook! object-oriented.

Interesting observation. If you intersect C and C++ what are you left
with?

Either poor C, poor C++, or syntax errors.
Well to some people type safety is free automated assistance.

I have no problem with free automated assistance, but free automated
dictation is another matter. Whether a pointer of type <foo> is meaningful
Do I smell a fundamentalist ideology?

No, you smell comp.lang.c, which is about C, not C++. If you want to discuss
C++, there's a whole nother newsgroup for that. And if you want to discuss
programming in general, there's a newsgroup for that, too.

I don't know what you are talking about. You cut and paste, you change
the target variable and miss the sizeof variable.

Oh, okay, I see what you mean. I thought you were talking about types, not
objects. The reason I didn't "get it" immediately is probably because I
find it quicker to type p = malloc(n * sizeof *p); than to invoke a copy
operation, a move operation, a paste operation, and two edits. Copy-paste
is expensive compared to typing when the amount to be copied is low, and
silly when the amount to be copied is high (because you're missing an
opportunity for re-factoring).
Ok, you've just
introduced a silent error, that's many hours of debugging waiting to
happen.

Perhaps I need more practice. I generally don't manage to make debugging
last more than a few minutes.
 
C

CBFalconer

Richard said:
(e-mail address removed) said:



If you redefined sizeof you wouldn't be programming in C any more.
When you have a sensible argument, wake me up.

You might as well give it up and save the bandwidth. Websnarl is
never going to write portable conforming code anyhow. He also
thinks that all C systems have 32 bit integers, for example. Just
point out the errors for the benefit of others.
 
A

Al Balmer

Fiirst of all, you
have not explained how the macro is error prone, while the above is so
obviously susceptable to cut-and-paste errors.

I've found that all cut-and-paste errors can be eliminated by avoiding
cut-and-paste.
 

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
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top