tags:

views:

1144

answers:

8

In this question, someone suggested in a comment that I should not cast the results of malloc. I.e.

int *sieve = malloc(sizeof(int)*length);

rather than

int *sieve = (int *)malloc(sizeof(int)*length);

Why would this be the case?

+4  A: 

In C you get an implicit cast from void* to any other (data) pointer.

EFraim
A: 

It's optional. Typically you do the cast to avoid compiler warnings.

Marco

Marco
You won't get a warning because a void pointer can always be cast to any other pointer.
dreamlax
Thus, if you get a warning without the cast, your code has a bug, probably not including <stdlib.h>.
Lars Wirzenius
Or he has an ancient libc version, where malloc returns a (char *)-pointer: http://en.wikipedia.org/wiki/Malloc
quinmars
+6  A: 

In C, you don't need to cast the return value of malloc. The pointer to void returned by malloc is automagically cast to the correct type. However, if you want your code to compile with a C++ compiler, a cast is needed. A preferred alternative among the community is to use the following:

int *sieve = malloc(sizeof *sieve * length);

which additionally frees you from having to worry about changing the right-hand side of the expression if ever you change the type of sieve.

Casts are bad, as people have pointed out. Specially pointer casts.

dirkgently
In the preferred alternative, what is "a" ?
Thomas L Holaday
Typo. Thanks though!
dirkgently
+32  A: 

You don't cast the result, since:

  • It is unnecessary, as void * is automatically and safely promoted to any other pointer type.
  • It can hide an error, if you forgot to include <stdlib.h>.
  • It adds clutter to the code, casts are not very easy to read (especially if the pointer type is long).
  • It makes you repeat yourself, which is generally a badness.
unwind
True. However, in C++ the cast is required, so if you want your code to work in both, you'll have to compromise. But in pure C, don't do the cast for the reasons you stated.
jalf
Agreed with @jalf. My code normally compiles under C or C++ compilers, even though it is primarily C. I sometimes use /*=C++=*/ comments to indicate why the cast is present.
Jonathan Leffler
amen for a straight C answer, none of this C++ nonsense
Matt Joiner
+8  A: 

In C you can implicitly cast a void pointer to any other kind of pointer, so an explicit cast is not necessary. Using one may suggest to the casual observer that there is some reason why one is needed, which may be misleading.

Visage
+4  A: 

As other stated, it is not needed for C, but for C++. If you think you are going to compile your C code with a C++ compiler, for which reasons ever, you can use a macro instead, like:

#ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif

That way you can still write it in a very compact way:

int *sieve = NEW(int, 1);

and it will compile for C and C++.

quinmars
Since you're using a macro anyway, why don't you use `new` in the definition of C++?
Hosam Aly
Because there is no reason to do so. It is mainly for C programs that are compiled with a C++ compiler. If you are going to use 'new', the only thing you get are problems. You need then also a macro for free. And you need a macro to free an array, a differentiation that doesn't exists in C.
quinmars
Not to mention if it's not you who frees the memory but maybe a C library you are using, etc. Many possible problems without any gain.
quinmars
Hmmm... I didn't think of that. Is it an error to use `free()` to free memory allocated with `new`?
Hosam Aly
Heh, I always thought so, but I'm not 100% sure. Maybe a good SO-question :)
quinmars
+3  A: 

I like this explanation because it's throughout, talking about possible goodness and bad consequences: Casting.

Johannes Schaub - litb
A: 

This is kind of off topic, but a lot of people here I think are being a little harsh on casting. There are perfectly legitimate reasons to do it, like the following:

int x = 1;
int y = 2;
double z;
z = (double) x / (double) y;

Lest we forget our painful integer division bugs!

Bob Somers
It was about casting the return of malloc. Of course, casting is sometimes necessary - but casting in C should not be done lightly. It can hide a lot of bugs, and explicit cast bypass the C system (C is nothing more than a typed assembler after all :) ).
David Cournapeau