Common misconceptions about C (C95)

N

Nobody

Ioannis's web page itself says:

| Misconception 10: Invokations of malloc(), calloc(), and realloc(),
| need casting.
...
| Clarification: Casting is not needed
...

Should say:

Misconception 10: whether or not to cast the return value of malloc() etc
has a definitive answer and isn't at all controversial.
....
Clarification: asking whether or not to cast the return value of malloc()
etc will start a heated discussion with a 26% chance of degenerating into
an all-out flame-war.
 
K

Keith Thompson

Ioannis Vranos said:
The page looks OK in my laptop (1920x1080 resolution). :)

But the code you've been posting here has been widely spaced.

I've preserved the blank lines in the above quotation.
The license must be included in the document to be in effect.

Hmm. I wonder if it has to be in the web page itself, or if a web
page with a link to the license could be considered a single document.
Not a question for this newsgroup. Perhaps you could ask in
gnu.misc.discuss; they could use some actual non-flame posts.
 
K

Keith Thompson

Nobody said:
C doesn't care about either implicit or explicit casts of void* to other
pointers.
[...]

There's no such thing as an implicit cast. A cast is an explicit
conversion.
 
H

Hallvard B Furuseth

Keith said:
No, casting the result of malloc is considered poor practice in C.
This is covered in the comp.lang.c FAQ, <http://www.c-faq.com>.

Except in cases when it isn't, also as covered by the FAQ:)
Like if you want some code snippets compilable as both C and C++.

I like to classify this one under the rule "make wrong code look wrong",
quoting to Joel Spolsky:
http://www.joelonsoftware.com/articles/Wrong.html

This:

p = malloc(sizeof(struct foo));

is poor code because you have to check (or remember) the declaration of
p to see if it really has type struct foo, even though that easily could
have been avoided with one of these:

p = malloc(sizeof(*p));
p = (struct foo *) malloc(sizeof(struct foo));

In the latter case p might still have the wrong type, but at least
you can tell at a glance that the compiler will complain if so.
 
H

Hallvard B Furuseth

Ioannis said:
The page looks OK in my laptop (1920x1080 resolution). :)

And if you remove most style and font stuff, use <pre> instead of <br>
and &nbsp; for formatting of code, it'll even look good on screens and
browsers with other setups than yours.

I also suggest to put the misconceptions in quotes, to visually separate
what you do not claim from what you do.
 
N

Nick

You are not allowed to discuss C99 in CLC...

Seriously, the "not casting the return value of malloc()" shibboleth
arose mainly out of C89 considerations (the only version approved by
alpha male Dicky H).

Do you recommend I should rewrite:

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

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?
 
D

Default User

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

Use of malloc() is C++ is normally poor practice. There's a small
subset of writers who create code that needs to compile under both
languages. They should be concerned about cross-language compatibility.
Others should not.




Brian
 
S

Seebs

So if I use a C99-mode compiler (or -Wmissing-prototypes or
equivalent), the major (sole?) reason for not casting vanishes, right?

Not really. The big reason not to do it is that it's not necessary and
distracts from what you're doing.

int x = 0, *p;
char *s;

x += (int) 1;
s = (char *) "hello";
p = (int *) &x;
(void) assert(((char *) s)[(int) x] == (int) (char) 'e');

You get the idea.

-s
 
S

Seebs

Misconception 10: whether or not to cast the return value of malloc() etc
has a definitive answer and isn't at all controversial.
...
Clarification: asking whether or not to cast the return value of malloc()
etc will start a heated discussion with a 26% chance of degenerating into
an all-out flame-war.

I would endorse this answer as factually accurate.

-s
 
S

Seebs

p = malloc(sizeof(*p));
p = (struct foo *) malloc(sizeof(struct foo));
In the latter case p might still have the wrong type, but at least
you can tell at a glance that the compiler will complain if so.

In the former case, you've guaranteed that it'll be the right type no
matter what. In the latter case, you've invited a maintenance programmer
to later change it to:

p = (struct bar *) malloc(some stuff I didn't read);

If the compiler doesn't notice that, then the maintenance programmer is
probably done.

-s
 
E

Eric Sosman

gwowen said:
So if I use a C99-mode compiler (or -Wmissing-prototypes or
equivalent), the major (sole?) reason for not casting vanishes, right?

A C99 compiler must complain about an attempt to call a
function that has not been declared. It need not complain
about a call to a function that has been declared with no
prototype. From my reading of the info, -Wmissing-prototypes
controls a gcc complaint at the point where the function is
defined, not where it is called; -Wimplicit-function-declaration
is probably the flag you're thinking of.

But yes: With suitable compiler versions and/or flags, this
reason for omitting the cast on malloc() disappears. Isn't that
the wrong question, though? Why search for reasons to remove
extraneous baggage; if the baggage is of no use, it shouldn't
have been there to begin with!

#include <stdio.h>
#define VSUPPRESS 1
int (main)(void) {
{\
(*(int (*)(const char*,...))(printf))
(((char*)"Hello, world!""\n"))
}\
return (42), 0;
#if VSUPPRESS
}
#undef SUPPRESSV
#else
#endif
 
H

Hallvard B Furuseth

Seebs said:
In the former case, you've guaranteed that it'll be the right type no
matter what.

Unless, as I just mentioned, you need the code to compile as C++.
Also the "right type" isn't of any help if p is void*.

But sure, I normally prefer the former version too.
In the latter case, you've invited a maintenance programmer
to later change it to:

p = (struct bar *) malloc(some stuff I didn't read);

And in the former case I've "invited" the maintenance programmer to
change it to:

r = malloc(some stuff I didn't read);

except I don't invite maintenance programmers to not even look at the
entire line they change.

Incidentally, if he changes the type of p from void* to struct bar*, it
is the second version and not the first which the compiler will catch.


Anyway, my point was that with all four versions above (the originals
and the broken "maintaned" code), you only need to look at a single line
in isolation regarding this particular bug. Which makes a bug fairly
noticable. With

p = malloc(sizeof(struct foo));

you need to look in two different places to see if there is a bug - the
malloc line and the declaration.
 
S

Seebs

Unless, as I just mentioned, you need the code to compile as C++.

Which is bad style to begin with. :)
Also the "right type" isn't of any help if p is void*.

In which case, you're probably doing something wrong.
And in the former case I've "invited" the maintenance programmer to
change it to:

r = malloc(some stuff I didn't read);

except I don't invite maintenance programmers to not even look at the
entire line they change.

You are very optimistic.
Incidentally, if he changes the type of p from void* to struct bar*, it
is the second version and not the first which the compiler will catch.
True.

Anyway, my point was that with all four versions above (the originals
and the broken "maintaned" code), you only need to look at a single line
in isolation regarding this particular bug. Which makes a bug fairly
noticable. With
p = malloc(sizeof(struct foo));
you need to look in two different places to see if there is a bug - the
malloc line and the declaration.

True. In practice, I've never had it be an issue -- if I'm calling malloc,
I'm usually visibly using the thing in a way which matches the usage.

Basically, I've seen more people show up with weird crashes due to a
cast malloc than due to an uncast one.

-s
 
K

Keith Thompson

Hallvard B Furuseth said:
Except in cases when it isn't, also as covered by the FAQ:)
Like if you want some code snippets compilable as both C and C++.

I know of only two cases where casting the result of malloc in C
makes sense.

One is when you need to compile the same code as both C and C++.
Given C++'s ability to interface to compiled C code, this is
very rarely necessary. (It can make sense for header files to be
compatible, but header files shouldn't contain calls to malloc.)

The other is when you're stuck using a pre-ANSI implementation
in which malloc() returns char* rather than void*. This also is
vanishingly rare -- and such old compilers are likely to allow an
implicit conversion from char* to some_type* anyway.

Nearly all style rules are conditional, in the sense that once you
understand why the rule makes sense, you can justify breaking it in
some cases.
I like to classify this one under the rule "make wrong code look wrong",
quoting to Joel Spolsky:
http://www.joelonsoftware.com/articles/Wrong.html

This:

p = malloc(sizeof(struct foo));

is poor code because you have to check (or remember) the declaration of
p to see if it really has type struct foo,
Agreed.

even though that easily could
have been avoided with one of these:

p = malloc(sizeof(*p));
p = (struct foo *) malloc(sizeof(struct foo));

In the latter case p might still have the wrong type, but at least
you can tell at a glance that the compiler will complain if so.

And what advantage does the second form have over the first? (Hint:
None at all.) The second form lets you detect a type mismatch
at compile time, but only if the two occurrences of "struct foo"
are kept in synch. The first avoids the possibility of a type
mismatch in the first place (again, if both occurrences of "p" are
kept in synch, but IMHO that's easier to do if you're accustomed
to the idiom).

Casts in general are potentially dangerous, since the bypass type
checking. If you get into the habit of using casts as little as
possible, it's easier to verify that the few you do use actually
make sense. The more casts you use, the harder this is.
 
K

Keith Thompson

Seebs said:
I would endorse this answer as factually accurate.

Yes, it's factually accurate, but less *useful* than an answer that
discourages C programmers from cating the result of malloc().
 
S

Seebs

Yes, it's factually accurate, but less *useful* than an answer that
discourages C programmers from cating the result of malloc().

That depends! In terms of amount of programmer time wasted, I'd guess
that making a recommendation costs more than either answer does. :p

-s
 
J

jacob navia

Richard Harter a écrit :
Yu have to appreciate that Kenny doesn't care about the actual
issues of writing and using C.

If you care to search in the archives, Kenny has sometimes given
very good answers to questions posed here.
His chosen function is mocking
the "regulars".

Yes, That is why I think he is a good poster here.
In his fantasy world Heathfield is a Svengali
figure who dominates c.l.c with an in-group clique.

That analysis is correct.
According to
Kenny the regulars have nothing of consequence to say about C;
rather they spend their time putting down the pretensions of
inferiors by pointing out clique nominated coding errors.

I have posted code here, proposing a container library for C.
Heathfield answered that he did not want to be involved
"with a looser" and never participated in a meaningful way
in those discussions. Neither Mr Thompson, nor most of the
clique in c.l.c. They have nothing to say about an improvement
of C, or about software engineering or about just anything
positive.

Iwas surprised that the standards committee decided to fix asctime(),
and I suspect strongly that my personal campaign against it was
one of the reasons the committee decided to fix it. Heathfield and
the others of the clique were always trying to justify asctime()
misgivings or downplaying the issue's importantce.

What the evolution of C is concerned, Heathfield (and Co) are
always complaining that standard C is not widely implemented,
ignoring all the implementations of the standard. Heathfield
uses a compiler version from the last century, and then it says
that gcc doesn't implement C99 even if he knows (as everybody
else) that C99 is quite well implemented in gcc, in the
linux versions at least.
Kenny will be happy to list them for you - he does it as a
regular thing. They include such things as void main(), casting
malloc, i = i++, etc.

Thousands of messages about those "questions" pollute this group
and the insistence of the regulars to discuss those "issues"
AD NAUSEAM makes this group specially boring.

In my posts I try to improve the technical level of this group by discussing
interfaces, ways of doing things, abstract data types, etc. Neither
Mr Thompson nor Mr Heathfield are ever present in those discussions.

Obvious.

What could they possibly say?

Kenny doesn't care whether they are coding
errors or not - as far as I can tell he doesn't have any interest
in C as such.

This is your unjustified personal opinion. I could say that YOU
have no interest in C either. You never bring your code here, or
bring subjects about programming in C in general. Can you please
tell me when was the last time you proposed something to discuss here?

Thanks.

To him the "errors" in his little list are
shibboleths, tokens by which the insiders know each other and
establish their credentials.

Obviously there are many other errors that could be dicussed. But
they aren't. Only those are selected, to recognize who is a member
of their group.
Infinity is one of those things that keep philosophers busy when they
could be more profitably spending their time weeding their garden.

Weeding the garden is the activity of failed philosophers, unable to
grasp what makes us human: Infinity.
 
S

Seebs

If you care to search in the archives, Kenny has sometimes given
very good answers to questions posed here.

He has, occasionally.
Yes, That is why I think he is a good poster here.

This undermines my confidence in you, actually.
That analysis is correct.

I don't buy it at all.
I have posted code here, proposing a container library for C.

Yes.

And I gave you detailed explanations of why I thought it was the wrong
problem to solve, and a solution to this problem would not be of great
value to many C programmers. You may not agree with those explanations,
but you can't deny that I engaged at some length to talk about them.
Heathfield answered that he did not want to be involved
"with a looser" and never participated in a meaningful way
in those discussions. Neither Mr Thompson, nor most of the
clique in c.l.c. They have nothing to say about an improvement
of C, or about software engineering or about just anything
positive.

Even assuming we just sort of randomly guess at who you think is "the
clique", I don't think I buy that. I've seen long discussions from
all of these people about C, and about proposed improvements to C.

Don't mistake disagreeing with you about what would be an improvement
for disinterest in improvements.
Iwas surprised that the standards committee decided to fix asctime(),
and I suspect strongly that my personal campaign against it was
one of the reasons the committee decided to fix it.

This would be pretty surprising to me, simply because my experience was
that the committee looked at defect reports, not at posts on Usenet.
Heathfield and
the others of the clique were always trying to justify asctime()
misgivings or downplaying the issue's importantce.

Unless I misremember, the "fix" is simply to point out that, yes, it's
possible for the sample implementation given to produce undefined behavior
in some circumstances, and yes, here's what those circumstances are.

I wouldn't consider this a "fix" myself.

On the other hand, I haven't used asctime in over 15 years, and it was on
the list of things, like gets, that I consider it an error for someone to
use.
What the evolution of C is concerned, Heathfield (and Co) are
always complaining that standard C is not widely implemented,
ignoring all the implementations of the standard.

Huh. I guess I'm not part of "and Co", then, because I use C99 features
without really paying attention to them. They work widely enough fo me.
Heathfield
uses a compiler version from the last century, and then it says
that gcc doesn't implement C99 even if he knows (as everybody
else) that C99 is quite well implemented in gcc, in the
linux versions at least.

It's not complete, though, so if someone asked me whether it supported
C99, I'd say "not completely, but it seems to do pretty well."
Thousands of messages about those "questions" pollute this group
and the insistence of the regulars to discuss those "issues"
AD NAUSEAM makes this group specially boring.

Well, one solution would be to figure out how to get people to stop posting
nonsense about them. If you can do that, poof, they go away.
In my posts I try to improve the technical level of this group by discussing
interfaces, ways of doing things, abstract data types, etc. Neither
Mr Thompson nor Mr Heathfield are ever present in those discussions.

Except you just pointed out how Heathfield participated in a previous one.
That you didn't like or agree with his participation doesn't mean he didn't
offer a technical opinion.
This is your unjustified personal opinion. I could say that YOU
have no interest in C either.

But there'd be a big difference, which is that it'd be obviously wrong --
he posts about C fairly often.
You never bring your code here, or
bring subjects about programming in C in general. Can you please
tell me when was the last time you proposed something to discuss here?

Not all discussion has to be proposals of discussions. Right now, the C
stuff I'm working on is nearly all system-dependent, so I don't have much
new to say about C in general, but I like to hang out so I can answer
peoples' questions and try to get them unstuck.
Obviously there are many other errors that could be dicussed. But
they aren't. Only those are selected, to recognize who is a member
of their group.

This makes no sense. None of the people you accuse of this start these
discussions. These are, after all, FAQs -- because people keep asking
them.

But hey, maybe we should do an experiment. You claim that this clique is
obvious.

Okay. How about the people who think it's obvious each, independently, write
down a list of the members of the clique, and the positions which are agreed
upon by all those members. I doubt you'd end up with enough agreement for
people to find it persuasive, even if we ignore the fact that many of your
statements about what other people say or do are flatly incorrect.

-s
 
K

Keith Thompson

jacob navia said:
I have posted code here, proposing a container library for C.
Heathfield answered that he did not want to be involved
"with a looser" and never participated in a meaningful way
in those discussions.

I certainly don't recall Richard Heathfield ever referring to you
as a loser (or a looser). Your use of quotation marks implies
that it's something he actually wrote. You should either support
this claim with a citation of the article in which he said this,
or retract it. I don't seriously expect you to do either.
Neither Mr Thompson, nor most of the
clique in c.l.c. They have nothing to say about an improvement
of C, or about software engineering or about just anything
positive.

You can repeat this as often as you like. It's still not true.
(I'm not going to say it's a lie; it's conceivable that you actually
believe it.)

You posted "Proposal for the C library in the new standard"
in comp.std.c on 2009-04-19. Of the 44 articles in the thread,
4 were mine.

You posted "Past overflow discussion" in comp.std.c on comp.lang.c
on 2009-09-04. Of the 33 articles in the thread, 4 were mine.

You posted "Zero overhead overflow checking" in comp.std.c and
comp.lang.c on 2009-09-07. Of the 110 articles in the thread,
22 were mine.

You posted "Updated proposal for overflow handling" in comp.std.c
on 2009-09-11. Mine was the only response.

And so on.

[...]
In my posts I try to improve the technical level of this group by discussing
interfaces, ways of doing things, abstract data types, etc. Neither
Mr Thompson nor Mr Heathfield are ever present in those discussions.

Obvious.

What could they possibly say?

See above.

[...]
 

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
474,007
Messages
2,570,266
Members
46,865
Latest member
AveryHamme

Latest Threads

Top