K&R-2 -- malloc() casts 
Author Message
 K&R-2 -- malloc() casts

In a recent article (now expired where I read news), I advised somebody
that it was wrong to cast the return value from malloc().  Subsequently,
a couple of people responded to this article by quoting from page 142 of
K&R-2:

    In C, the proper method is to declare that malloc returns a
    pointer to void, then explicitly coerce the pointer into the
    desired type with a cast.

Since this statement is directly at variance with my advice and since I
am well-known as an ardent (some would use a stronger word) proponent of
K&R-2, these people quite naturally wondered how these two positions
could be reconciled.

They can't.  In this case, K&R-2 is wrong [see note below].

I think it might be useful to repeat here why such a cast is a bad idea.
First, the cast serves no useful purpose in Standard C if other things
have been done right -- i.e., the variable (`p' in the example above)
has been declared as some suitable kind of pointer, and <stdlib.h> has
been included.  In that case, the `void *' returned by malloc() will be
converted automatically to right kind of pointer.  Second, if `p' is not
a suitable variable or <stdlib.h> has not been included or the cast is
wrong, the very presence of the cast is likely to prevent the compiler
from issuing a useful diagnostic.

In pre-ANSI C -- as described in K&R-1 -- malloc() returned a `char *'
and it was necessary to cast its return value in all cases where the
receiving variable was not also a `char *'.  The new `void *' type in
Standard C makes these contortions unnecessary.

To save anybody from the embarrassment of leaping needlessly to the
defence of K&R-2, I asked Dennis Ritchie for an opinion that I could
quote on the validity of the sentence cited above from page 142.  He
replied:

    In any case, now that I reread the stuff on p. 142, I think it's
    wrong; it's written in such a way that it's not just defensive
    against earlier rules, it misrepresents the ANSI rules.

Despite this small flaw, I am still quite happy to continue to recommend
K&R-2 as the best book to use in learning C -- so anybody who hoped this
might stop me will be disappointed :-)

--



Sat, 13 Sep 1997 11:49:15 GMT  
 K&R-2 -- malloc() casts

Quote:
>They can't.  In this case, K&R-2 is wrong [see note below].

>I think it might be useful to repeat here why such a cast is a bad idea.
>First, the cast serves no useful purpose in Standard C if other things
>have been done right -- i.e., the variable (`p' in the example above)
>has been declared as some suitable kind of pointer, and <stdlib.h> has
>been included.  In that case, the `void *' returned by malloc() will be
>converted automatically to right kind of pointer.  Second, if `p' is not
>a suitable variable or <stdlib.h> has not been included or the cast is
>wrong, the very presence of the cast is likely to prevent the compiler
>from issuing a useful diagnostic.

>In pre-ANSI C -- as described in K&R-1 -- malloc() returned a `char *'
>and it was necessary to cast its return value in all cases where the
>receiving variable was not also a `char *'.  The new `void *' type in
>Standard C makes these contortions unnecessary.

Yes, K&R-2 is wrong about the need for a cast of the returned pointer
from malloc().  But I wonder: I read somewhere (I think it was in one
of Bjarne Stroustrup's books) that K&R-2 source compiled unmodified
under C++.  That might explain the cast, because C++, unlike ANSI C,
does not stupidly allow the silent cast of (void *) to a non-void
pointer, which violates strong typing.  C code wanting to be
compatible with C++ must include explicit type casts away from (void
*).  I always use the explicit cast.  In any case, I think that's a
good idea because it forces you to remember that you know something
that the compiler doesn't about the correct type of the object pointed
to.

It is unfortunately true that manually adding in a cast is an
imperfect solution because you lose type-checking that way also.  Of
course, in C++ you usually use operator new() instead of malloc(),
which returns a typed pointer when used in a new() expression, neatly
sidestepping the most common use of a conversion from (void *) to a
typed pointer.
--

Applied Dynamics International
3800 Stone School Road
Ann Arbor, MI 48108-2499



Sat, 13 Sep 1997 03:00:00 GMT  
 K&R-2 -- malloc() casts


Quote:
> In a recent article (now expired where I read news), I advised somebody
> that it was wrong to cast the return value from malloc().  Subsequently,
> a couple of people responded to this article by quoting from page 142 of
> K&R-2:

>     In C, the proper method is to declare that malloc returns a
>     pointer to void, then explicitly coerce the pointer into the
>     desired type with a cast.

> Since this statement is directly at variance with my advice and since I
> am well-known as an ardent (some would use a stronger word) proponent of
> K&R-2, these people quite naturally wondered how these two positions
> could be reconciled.

> They can't.  In this case, K&R-2 is wrong [see note below].

> I think it might be useful to repeat here why such a cast is a bad idea.
> First, the cast serves no useful purpose in Standard C if other things
> have been done right -- i.e., the variable (`p' in the example above)
> has been declared as some suitable kind of pointer, and <stdlib.h> has
> been included.  In that case, the `void *' returned by malloc() will be
> converted automatically to right kind of pointer.  Second, if `p' is not
> a suitable variable or <stdlib.h> has not been included or the cast is
> wrong, the very presence of the cast is likely to prevent the compiler
> from issuing a useful diagnostic.

> In pre-ANSI C -- as described in K&R-1 -- malloc() returned a `char *'
> and it was necessary to cast its return value in all cases where the
> receiving variable was not also a `char *'.  The new `void *' type in
> Standard C makes these contortions unnecessary.

> To save anybody from the embarrassment of leaping needlessly to the
> defence of K&R-2, I asked Dennis Ritchie for an opinion that I could
> quote on the validity of the sentence cited above from page 142.  He
> replied:

>     In any case, now that I reread the stuff on p. 142, I think it's
>     wrong; it's written in such a way that it's not just defensive
>     against earlier rules, it misrepresents the ANSI rules.

> Despite this small flaw, I am still quite happy to continue to recommend
> K&R-2 as the best book to use in learning C -- so anybody who hoped this
> might stop me will be disappointed :-)

> --


Was Dr. Ritchie thinking of "Clean C" (i.e. the common ground of ANSI-C and
compatibilities with C's new sibling) at that time, since you mentioned in
one of your articles that you were exclusively informed of the reasons on
the _upward_ compatibility of his programs?  

As far as the Std-C is concerned, the oversight is only a minor hiccup.  But
looking into Harbison and Steele's 4th edition,  I salute Dr. Ritchie for
his bold and perspicacious foresight in anticipating current trend years
ago, in preparing those who would be interested to write "Clean C" which are
both acceptable to Std-C and its new sibling.

Allow me to quote from H&S4 page xviii: "Clean C is a kind of "strict ISO
C," without some of the anachronisms kept for compatibility.", and  Dr.
Ritchie demonstrated that some eight years ago.  My only contention is that
all C programmers ought to be just as versatile.

__
Ignatius



Sun, 14 Sep 1997 10:05:57 GMT  
 K&R-2 -- malloc() casts

writes:
<snip>
|> It is unfortunately true that manually adding in a cast is an
|> imperfect solution because you lose type-checking that way also.  Of
|> course, in C++ you usually use operator new() instead of malloc(),
|> which returns a typed pointer when used in a new() expression, neatly
|> sidestepping the most common use of a conversion from (void *) to a
|> typed pointer.

Fine.

With liberal use of typedef, the corresponding solution in C is probably to
hide casts in well understood places:

#define NEW(x,n) ((x*)malloc(sizeof(x)*n)) /* Result of malloc is unchecked */

And use it as

typedef int (*Functab[10]) (int, int);
Functab *table_of_tables = NEW(Functab,64);

This is almost as good as not using casts.

Cheers
Tanmoy
--

Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87544-0285,USA H:#3,802,9 St,NM87545
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003   voice: 1 (505) 665 4733    [ Home: 1 (505) 662 5596 ]



Mon, 15 Sep 1997 09:57:08 GMT  
 K&R-2 -- malloc() casts

: Yes, K&R-2 is wrong about the need for a cast of the returned pointer
: from malloc().  But I wonder: I read somewhere (I think it was in one
: of Bjarne Stroustrup's books) that K&R-2 source compiled unmodified
: under C++. [...]

I think this is stated in the introduction of K&R-2 itself.  I remember
asking Bjarne Stroustrup about it, and he pointed out that they did this
exactly because of the stronger type-checking rules of C++, which allowed
them to get further bugs out of their code.  Or, in this case, leave in a
cast that is needed for C++ but not for C.  (But then, the possibly
invalid passing of strcmp to qsort, or some such, did slip through!)

--
                        +----------------------------------+
Martin Sohnius          | The first rule in politics:      |
Novell Labs Europe      |  "When in a hole, stop digging." |
Bracknell, England      |     - Denis Lord Healey          |
+44-1344-724031         +----------------------------------+
                        (I speak for myself, not for Novell or anyone else.)



Sat, 11 Oct 1997 03:00:00 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. (void *) & casting the pointer returned by malloc

2. malloc: to cast or not to cast

3. KC/OP-KS-Visual C++/MFC/COM Developers

4. KC/OP-KS-Visual C++/MFC/COM Developers

5. casting malloc question.

6. casting malloc question.

7. never cast malloc?

8. casting return value from malloc

9. type casting malloc() to void *

10. cast to malloc

11. Why not cast the rerurn from malloc()?

12. More about casting malloc()...

 

 
Powered by phpBB® Forum Software