Casting the return value of malloc() ?

R

RocTheEngy

Not that I can think of. Testing the return value, on the other hand, is
crucial.

I suggest you find someone who advocates the cast, and ask them why. Most
likely, they won't know. In the event that you find someone who does know
why they're casting, why not present this group with the reason he or she
gives you, and ask us what we think of it?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999


The professor at my college where I learned C (he was newly hired at
the time; almost 20 years ago) was the first person to teach C at
the university. Previous programming classes were purely pascal.

He was therefore, by defacto standard, the "guru" and not to be
questioned... (at least not by us undergrads).

He was _adamant_ that the malloc() family *required* casts. To this
day,
the only answer I recall him giving is "...to give the compiler a
warm,
fuzzy feeling". To inquire further left one with the feeling that
your next test grade may suffer if you pressed him. Looking back, I
suspect the intimidation was to avoid embarrasment.

The system, as best I recall, was some type of VAX. It ran a flavor
of Unix, and we compiled our code with "cc" (not gcc). I used that
programming convention for years on many platforms until I read the
CLC FAQ.

To this day, many of us would like to know WHY we were
required to cast for malloc's. I wish I could remember more details.
For all I now, he may have had a reason. Beats me.
 
R

RocTheEngy

RocTheEngy said:











20 years ago, he was *right*.

The language changed... 19 years ago.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999- Hide quoted text -

- Show quoted text -

I said _almost_ 20 years ago. :) It was 1991...

But to understand your statement; there was a time when this
convention was correct?
(i.e. required)
 
I

Ian Collins

RocTheEngy said:
I said _almost_ 20 years ago. :) It was 1991...

But to understand your statement; there was a time when this
convention was correct?
(i.e. required)
Before C was standardised, void wasn't part of the language and malloc
returned char*
 
P

Peter Nilsson

Flash Gordon said:
Nick Keighley wrote, On 03/10/08 09:27:

Let's not forget Ritchie and Kernighan.
I *think* he was calling the customers dumbos, not the
authors of the library.

Plauger shares the view of his customers. So any criticism
of his customers must be applied to Plauger himself, if
consistency is to hold.

Here's what he had to say in 2004...

"What I find interesting about this debate is the two
positions being espoused:

1) Omitting casts on malloc calls is acceptable, but
not necessarily virtuous.

2) Putting casts on malloc calls is stupid.

Those of us in the first camp are going to keep using
casts, and we're going to keep respecting those who
don't. It would be nice if we were granted a bit of
respect in turn, but what the hell. A closed mind
avoids the risk of having to change."
 
F

Flash Gordon

Peter Nilsson wrote, On 06/10/08 23:03:
Let's not forget Ritchie and Kernighan.

That was because there were no compilers conforming to ANSI C at the
time so they had to use a C++ compiler to get access to certain features.
Plauger shares the view of his customers. So any criticism
of his customers must be applied to Plauger himself, if
consistency is to hold.

I thought that his view was that it was the right thing for him to do it
because that was his customers' requirement.
Here's what he had to say in 2004...

"What I find interesting about this debate is the two
positions being espoused:

1) Omitting casts on malloc calls is acceptable, but
not necessarily virtuous.

2) Putting casts on malloc calls is stupid.

He missed a view some espouse...

3) Putting casts on malloc is virtuous
Those of us in the first camp are going to keep using
casts, and we're going to keep respecting those who
don't. It would be nice if we were granted a bit of
respect in turn, but what the hell. A closed mind
avoids the risk of having to change."

Well, at least some of the people who in general strongly disagree with
putting the casts in have accepted that sometimes there is a good
reason. So not everyone who is against casting has a completely closed
mind :)
 
I

Ian Collins

Flash said:
Peter Nilsson wrote, On 06/10/08 23:03:

That was because there were no compilers conforming to ANSI C at the
time so they had to use a C++ compiler to get access to certain features.
Like void!

I don't think the original K&R even mentions malloc. They do briefly
describe calloc, which is shown as returning char* so a cast is required.
 
P

Peter Nilsson

Flash Gordon said:
Peter Nilsson wrote, On 06/10/08 23:03:

That was because there were no compilers conforming to
ANSI C at the time so they had to use a C++ compiler to
get access to certain features.
<http://groups.google.com/group/comp.lang.c/msg/4a6ea4a63a610cac?
dmode=source>


I thought that his view was that it was the right thing for
him to do it because that was his customers' requirement.

<http://groups.google.com/group/comp.lang.c/msg/02411d85b17ce318?
dmode=source>

<snip>
 
N

Nick Keighley

The question is, why would you want to do this?

You can write programs that compile in both C
and Fortran.

that's just dumb. Try thinking instead of just repeating dogma.
Fortran doesn't look anything like C. Well written C compiles
with C++. That is a fact.


But again, why would you?

Here's the reasons I can think of:
  1) For curiosity's sake
  2) You are an idiot

whatever.
 
I

Ian Collins

Nick said:
that's just dumb. Try thinking instead of just repeating dogma.
Fortran doesn't look anything like C. Well written C compiles
with C++. That is a fact.
No it is not. The common subset of C and C++ compiles as C and C++.
There are a number of C constructs that are not valid C++.
 
J

James Kuyper

Nick said:
that's just dumb. Try thinking instead of just repeating dogma.
Fortran doesn't look anything like C. ...

Fortran code can also BE C code - with care, it can even behave in
equivalent ways when compiled with both types of compilers. Of course,
this relies upon complicated tricks that depend upon the different ways
in which the two languages handle comments. No one would recommend doing
so, which I believe was his whole point: it's possible, but why do it?

That approach wouldn't work with C and C++; they're too similar - with
the release of C99 they now have identical syntax for comments. However,
they are also sufficiently similar that you don't need to use that
approach, so the reference to Fortran was a bad argument.
... Well written C compiles
with C++. That is a fact.

It is a falsehood that bears a resemblance to the truth. C can be
written to compile with C++, and most of the restrictions needed to make
it compile with C++ are things that make the C code better (such as
mandatory use of prototypes). C code that compiles under C++ will
usually (but not always) behave the same way as when compiled under C.
With a little bit of additional care, it is possible to modify almost
any strictly conforming C90 program (and most C programs that don't
strictly conform to C90) so that it will compile with the same behavior
under either C or C++. An obvious exception is programs which are
designed to detect which language they were compiled with.

However, well written C code does NOT cast the value returned by
malloc(); and such code is a constraint violation for C++, unless the
destination is also a void*. Well written C code can and sometimes does
make use of identifiers that are reserved in C++. Also, well written C99
code can make use of constructs that are not supported by C++. Many C99
features will be supported in future versions of C++, but that hasn't
happened yet, and many features will never be supported.
 
R

Richard Tobin

Nick Keighley said:
Well written C compiles with C++. That is a fact.

In that case, to write C well you have to refer to a C++ reference,
because C++ reserves identifiers that a C programmer would otherwise
have no reason to avoid.

-- Richard
 
N

Nick Keighley

Ian Collins said:

a couple of people have said this. Are they C89 constructs?
I'm aware that a fair amount of C99 stuff is unlikely
to make it into C++ (eg. complex numbers).

And they are "well-written" constructs, too.

Nick, are you really saying that adding a cast to a call to a function
returning void * is either badly-written C or legal C++?

er, no.

char *fred = (char*)malloc(42);

is not particularly good C but it will compile with C++.
 
J

James Kuyper

Nick said:
a couple of people have said this. Are they C89 constructs?

Yes, many of them are. See appendix C of the C++ standard. It's 15 pages
long. Many of the constructs are very uncommon, many of them will never
appear in well-written C code. But some of them do occur with moderate
frequency even in well-written C code.
 
K

Keith Thompson

Peter Nilsson said:

In which Bjarne Stroustrup writes:
| Dennis Ritchie and Brian Kernighan are among the most thoughtful of
| people. They did have a choice at the time. If they had thought it
| important/best to leave malloc calls uncast they could have (1) used
| the ANSI C compiler or (2) edited the casts out in the final draft
| (after the final check with the ANSI C compiler) or (3) politely asked
| me for a compatibility feature in Cfront (we talked almost every day).
|
| I think it is safest to assume that when Dennis Ritchie and Brian
| Kernighan did something, it was because they wanted to do that and not
| the opposite.

But the errata list for K&R2 acknowledges that casting the result of
malloc isn't such a good idea after all.
<http://netlib.bell-labs.com/cm/cs/cbook/2ediffs.html>:

142 (section 6.5, toward the end): The remark about casting the
return value of malloc ("the proper method is to declare ... then
explicitly coerce") needs to be rewritten. The example is correct
and works, but the advice is debatable in the context of the
1988-1989 ANSI/ISO standards. It's not necessary (given that
coercion of void * to ALMOSTANYTYPE * is automatic), and possibly
harmful if malloc, or a proxy for it, fails to be declared as
returning void *. The explicit cast can cover up an unintended
error. On the other hand, pre-ANSI, the cast was necessary, and it
is in C++ also.

In which P.J. Plauger, replying to Richard Heathfield, writes:
| I thought I had given more than one reason, en passant, but here's a
| quick review. Indeed the first motivation we had for adding casts to
| malloc calls was to satisfy a market need to have all our Standard C
| library compile either as C or C++. The C++ Standard (thanks to me)
| deliberately permits the C library to have either extern "C" or
| extern "C++" linkage -- and we have serious customers for both
| flavors. Having done so, we then found reasons to make *all* of our
| C source code compilable as C++.
|
| Generally I avoid casts for the reason so often given -- they're so
| strong that they often hide problems. We add them where required for
| correctness, for portability, for C++ compatibility, and to quiet
| silly warnings. Our experience over the years is that the last
| category of casts do indeed raise the cost of maintenance -- we fix
| something here and the forgotten consequences there are masked by
| the cast, until we discover the bug by a painful runtime trace.
|
| But allocator casts often *help* us find bugs that arise during
| maintenance. The classic pattern is a structure declared here,
| containing a pointer to another structure declared somewhere else,
| for which storage is allocated there, and freed some other
| there. That's why we allocate N times the size of the thing we
| really want, cast the resultant pointer to a pointer to that type,
| and store it in what should be a compatible type of pointer. We've
| had the compiler inform us of bugs in both size and pointer types as
| the code changes under maintenance and enhancement.
|
| In our environment, bugs like failing to include stdlib.h get found
| and fixed in the first pass or two of code writing. We generally
| perform *many* passes over our code during development, and develop
| a companion set of tests. So the kind of bugs masked by casts on
| malloc are cheap to fix, while the kind exposed by such casts are
| much more expensive.

But I believe the bugs exposed by casting the result of malloc can be
avoided by using the clc-recommended idiom:

ptr = malloc(COUNT * sizeof *ptr);

even if "ptr" is some more complex expression.
 
K

Keith Thompson

Richard Heathfield said:
Nick Keighley said:


Sure. Several keywords, for a start, and automatic void * conversion.

You mean C++ keywords that are valid C89 identifiers, right? On first
reading, I thought you were talking about C keywords.

[...]
 
V

vippstar

Nick Keighley said:
Well written C compiles with C++. That is a fact.

It may be the case that it's correct C but not correct C++, and vice
versa.
Here's one of the best pages I've found on the net about C/C++
differences:
<http://david.tribble.com/text/cdiffs.htm>

Here's some code that doesn't work in C++, but does work in C,

#include <limits.h>

int main(void) {
char m[sizeof 'A'];
return m[CHAR_BIT == 8] = 0;
}

This takes advantage of the following difference, that 'A' in C has
type int, but in C++ has type char.
In C this code always works; in C++ it never works.
 

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,755
Messages
2,569,536
Members
45,010
Latest member
MerrillEic

Latest Threads

Top