Author |
Message |
Greg Bla #1 / 5
|
 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 |
|
 |
Franklin Ch #2 / 5
|
 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 |
|
 |
I. Won #3 / 5
|
 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 |
|
 |
Tanmoy Bhattachar #4 / 5
|
 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 |
|
 |
Martin Sohni #5 / 5
|
 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 |
|
|
|