162

Today I reached page 167 of The C Programming Language (second edition Brian W. Kernighan & Dennis M. Ritchie) and found that the author says I must cast malloc. Here is the part from the book:

7.8.5 Storage Management

The functions malloc and calloc obtain blocks of memory dynamically.

void *malloc(size_t n)

returns a pointer to n bytes of uninitialized storage, or NULL if the request cannot be satisfied.

void *calloc(size_t n, size_t size)

returns a pointer to enough free space for an array of n objects of the specified size, or NULL if the request cannot be satisfied. The storage is initialized to zero. The pointer returned by malloc or calloc has the proper alignment for the object in question, but it must be cast into the appropriate type, as in

int *ip;
ip = (int *) calloc(n, sizeof(int));

I already know that malloc (and its family) returns type void*, and there are good explanations why not to cast malloc.

But my question is: Why does the book say I should cast it?

Raedwald
  • 40,290
  • 35
  • 127
  • 207
Michi
  • 4,759
  • 6
  • 29
  • 51
  • 128
    Because the book is old. – Oliver Charlesworth Sep 18 '15 at 12:38
  • 12
    Because even the Sun has its dark spots, would be my answer. In other words, the book is wrong. It could be that the text predates the semantics for `void *`, and wasn't updated. See also [this answer](http://stackoverflow.com/a/28460192/28169). – unwind Sep 18 '15 at 12:38
  • 8
    @Michi The book has many factual and typographic errors (google K&R errata), it is only somewhat compatible with the C90 standard, it does not address the current C standard nor any changes in the language since 1990. Worst of all it is filled with bad programming practice, bad style and code which relies on poorly-specified behavior. All of which you have to unlearn if you become a professional C programmer. – Lundin Sep 18 '15 at 13:04
  • 1
    possible duplicate of [Do I cast the result of malloc?](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Mandrill Sep 18 '15 at 16:57
  • 8
    ...and contrast this with [Why does the compiler complain when I do not cast the result of malloc?](http://stackoverflow.com/questions/10568301/why-does-the-compiler-complain-when-i-do-not-cast-the-result-of-malloc?rq=1) So, for C - don't cast. For C++ - cast, but don't use `malloc` because it's NOT C++ - except when you have to - but you shouldn't - except...AGGGHHHHHH!!!!! :-) – Bob Jarvis - Reinstate Monica Sep 18 '15 at 17:29
  • 2
    @Mandrill have you read my Question ? I had to edit my Question for you. – Michi Sep 18 '15 at 18:15
  • 1
    @OliverCharlesworth is there a better/more relevant/ comparable text in comparison? – phillipsK Sep 23 '15 at 01:11
  • [Relevant page from the comp.lang.c FAQ](http://c-faq.com/malloc/cast.html) – Spikatrix Sep 24 '15 at 13:20

1 Answers1

223

From http://computer-programming-forum.com/47-c-language/a9c4a586c7dcd3fe.htm:

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.

alk
  • 66,653
  • 10
  • 83
  • 219
David Ranieri
  • 36,077
  • 6
  • 44
  • 85
  • 24
    So the return type of malloc was **char** and not **void**. Thank you. – Michi Sep 18 '15 at 12:57
  • 11
    It's also mentioned in the errata http://web.archive.org/web/20150205025553/http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html – nos Sep 18 '15 at 13:17
  • 18
    You mustn't read this book without that errata printed on a paper(s) next to you. – Lundin Sep 18 '15 at 13:19
  • @Lundin I will buy a new book with c11 standard. – Michi Sep 18 '15 at 13:22
  • 4
    @Michi - no, the return type was `char*`, not `char`. The two are vastly different. – Pete Becker Sep 18 '15 at 13:41
  • 2
    @PeteBecker Sir, that was a typo, i know that and i did explained in my Question. about return type of malloc wich is **void*** – Michi Sep 18 '15 at 13:44
  • 20
    @alk: exactly. By reading K&R you're listening to two gurus, which is ample ;-) – Steve Jessop Sep 18 '15 at 15:36
  • 1
    @Michi There was no `void` (or `void*`) in the original C language. `char*` was used as the generic pointer type then. – Barmar Sep 23 '15 at 13:28
  • @SteveJessop Yes there are two but you need to check the guru best before date on both of them. Says 1990. – Lundin Sep 25 '15 at 06:49
  • @KeineLust Would it be accurate to say that when malloc returns `char *`, the cast is actually required by the compiler to avoid a hard error? – trognanders Feb 14 '19 at 06:58