Why does C++ require a cast for malloc() but C doesn't?



I have always been curious about this - why do in C++ I have to cast return value from malloc but not in C?

Here is the example in C++ that works:

int *int_ptr = (int *)malloc(sizeof(int*));

And here is the example in C++ that doesn't work (no cast):

int *int_ptr = malloc(sizeof(int*));

I heard that in C, in fact, casting an output from malloc() is a mistake.

Can anyone comment on this topic?


Posted 2010-08-13T14:22:06.520

Reputation: 22 001

3@R.. go and learn D or Go or something – Quonux – 2013-07-14T20:20:12.107

C++ being more type sensitive requires you to specify the exact type via a cast. – Abhay – 2010-08-13T14:30:56.717

10This is not directly related to your question, but I think you want sizeof(int), not sizeof(int*). That said, it's even better to use sizeof *int_ptr, which guarantees that you'll be allocating the right amount of memory for whatever type int_ptr happens to point to. – bcat – 2010-08-13T14:31:30.270

5Why would you use malloc in C++? – SoapBox – 2010-08-13T14:31:53.280

1In C, the cast isn't wrong, but it is completely unnecessary. In C++, using void* or malloc() for anything (except using an interface designed for C) is almost certainly a mistake. – Mike Seymour – 2010-08-13T15:02:38.967

15In order to avoid all the -1's, I'm going to say this as a comment rather than an answer: because C++ sucks. – R.. – 2010-08-13T15:34:59.290



Several points:

C allows void pointers to be implicitly converted to any other object pointer type. C++ does not.

Casting the result of malloc() in C will supress a useful diagnostic if you forget to include stdlib.h or otherwise don't have a declaration for malloc() in scope. Remember that if C sees a function call without a prior declaration, it will assume that the function returns int. If you don't have a declaration for malloc() and you leave off the cast, you'll get a diagnostic to the effect that you're trying to assign incompatible types (int to pointer). If you cast the result, you supress the diagnostic and will potentially have runtime issues, since it's not guaranteed that converting a pointer value to an int and back to a pointer again will give you a useful result.

If you're writing C++, you should be using new and delete instead of malloc() and free(). Yeah, yeah, yeah, I've heard all the reasons why people want their code to compile as both C and C++, but the benefits of using the right memory management tool for the language outweigh the cost of maintaining two versions IMO.

Note: the void * type was added in the C89 standard; earlier versions of C had malloc() return char *, so in those versions the cast was required if you were assigning the result to a different pointer type. Almost everybody supports at least the C89 standard though, so the odds of you running into one of those older implementations is very, very low.

John Bode

Posted 2010-08-13T14:22:06.520

Reputation: 80 542

4Won't any modern compiler output a warning for a missing declaration of malloc(), regardless of casting issues? – Daniel Stutzbach – 2010-08-13T15:01:36.970

@Daniel: That also depends on your warning level. Cast warning usually shows up in a lower warning level than missing declaration. – Mehrdad Afshari – 2010-08-13T15:36:52.143

Maybe, but it's still best practice to leave the cast off anyway. – John Bode – 2010-08-13T15:43:00.957


That's because C++ is a strongly-typed language. In C++, implicit casts are only allowed if they are "widening", that is, if the new type can hold every value that the old type can hold. Casting from a smaller integer type to a larger integer type is allowed; casting from any pointer type to void* is allowed; casting from a subclass to its superclass is allowed. All other casts must be made explicitly, thereby telling the compiler "I know what I'm doing, this is not a mistake".

malloc() returns a void*, which could be anything, so the compiler cannot guarantee that your cast will succeed (or be meaningful). By using an explicit cast, you're telling the compiler that what you're doing is actually intentional.

C, OTOH, does not have such rigid casting rules; you can happily cast between any two types, and you as the programmer are responsible for making sure no bad things happen as a consequence.


Posted 2010-08-13T14:22:06.520

Reputation: 17 648

6I can implicitly cast an int to bool with no problem. – UncleBens – 2010-08-13T16:54:38.993

2"That's because C++ is a strongly-typed language." ... and C isn't!? – cdhowie – 2017-04-12T15:56:46.343

"C++ is a strongly-typed language." Eh. "Strongly typed" is pretty much meaningless as a term. Authors generally use it to mean "I like this language". "In C++, implicit casts are only allowed if they are "widening", that is, if the new type can hold every value that the old type can hold." Several problems with this: A "cast" is an explicit type conversion; if it's implicit, it's not a cast. C++ allows narrowing type conversions, just like C: int i = 1.3; float f = ULONG_MAX; compiles without errors. Converting Derived* to Base* is unsafe because of arrays. C++ allows it, C doesn't. – melpomene – 2018-09-17T07:45:05.110

"[In C] you can happily cast between any two types" Not true, e.g. you cannot convert to a struct type (whether explicitly (by casting) or implicitly). – melpomene – 2018-09-17T07:46:46.010


C supports implicit cast from void* to other pointer types. C++ disallows it.

One reason that it's frowned upon in C to explicitly cast the return value of malloc is that if the malloc signature is not included in the current compilation unit, the compiler will assume that the return type is int and implicit conversion of it to the pointer type you're assigning to results in a compile-time warning you'd immediately resolve. With an explicit cast, if you make this mistake, no warning will be issued.

Mehrdad Afshari

Posted 2010-08-13T14:22:06.520

Reputation: 339 985