Casting of void pointer returned by malloc()

S

SRR

Why is it discouraged to explicitly typecast the void pointer returned
by malloc(); function?

For example:
{
int *p;
p = (int*)malloc(2*sizeof(int)); /*Explicit casting is done, therfore
it is said to be a bad practice*/
/*Some codes*/
}

Please, explain why.

Thanks in advance.
 
M

mark_bluemel

Why is it discouraged to explicitly typecast the void pointer returned
by malloc(); function?

For example:
{
int *p;
p = (int*)malloc(2*sizeof(int)); /*Explicit casting is done, therfore
it is said to be a bad practice*/
/*Some codes*/

}

Please, explain why.

FAQ 7.7b <http://c-faq.com/malloc/mallocnocast.html>

I suggest you bookmark the FAQ and check it before asking questions.

NOTE: The problem discussed in FAQ 7.7b is a real one, and I've seen
it causing major problems on systems where a pointer is 64-bits, but
an integer 32...
 
C

Chris Dollin

SRR said:
Why is it discouraged to explicitly typecast

"cast". Not "typecast".
the void pointer returned by malloc(); function?

It's in the FAQ.

(Because you don't need to, and doing so can conceal a
serious mistake that the compiler is not /obliged/
to report.)
 
B

Ben Pfaff

SRR said:
Why is it discouraged to explicitly typecast the void pointer returned
by malloc(); function?

I don't recommend casting the return value of malloc():

* The cast is not required in ANSI C.

* Casting its return value can mask a failure to #include
<stdlib.h>, which leads to undefined behavior.

* If you cast to the wrong type by accident, odd failures can
result.

In unusual circumstances it may make sense to cast the return value of
malloc(). P. J. Plauger, for example, has good reasons to want his
code to compile as both C and C++, and C++ requires the cast, as he
explained in article <[email protected]>.
However, Plauger's case is rare indeed. Most programmers should write
their code as either C or C++, not in the intersection of the two.
 
E

Eric Sosman

SRR wrote On 03/06/07 11:18,:
Why is it discouraged to explicitly typecast the void pointer returned
by malloc(); function?

For example:
{
int *p;
p = (int*)malloc(2*sizeof(int)); /*Explicit casting is done, therfore
it is said to be a bad practice*/
/*Some codes*/
}

Please, explain why.

Counter-question: Why did you not cast the 2 as well?

p = (int*)malloc((size_t)2 * sizeof(int));

If your answer is something like "Because the 2 will be
converted from int to size_t anyhow, so the cast is just
useless baggage," observe that the answer applies with
equal force to casting the result of malloc().
 
B

bluejack

However, Plauger's case is rare indeed. Most programmers should write
their code as either C or C++, not in the intersection of the two.

I've known a few people to use a gcc in g++ mode to craft their own
superset of C: default parameters & function overloading. If you're
going to do that, you'll need to cast your return values as well.
There are probably some penalties, and I don't expect the purist crowd
to approve, but it can make for some sweet interfaces.
 
D

Dave Vandervies

I've known a few people to use a gcc in g++ mode to craft their own
superset of C: default parameters & function overloading. If you're
going to do that, you'll need to cast your return values as well.
There are probably some penalties, and I don't expect the purist crowd
to approve, but it can make for some sweet interfaces.

If you're writing code that requires a C++ compiler, you should be using
new instead of malloc, unless you're allocating memory that has to be
freed from C code (in which case the best solution is most likely to be
"fix your design"[1]).

C is best written in C. C++ is best written in C++. This is not a
"purist" argument; it's sound engineering practice.


dave

[1] The solution that's next in line for likeliness-of-being-best is to
use a type-safe template wrapper that lets you say
my_ptr=typesafe_malloc<type>(count);
and does the cast inside the template's implementation. So you
still shouldn't have more than one malloc call in your entire code
base that has a cast in front of it.
 
F

Flash Gordon

bluejack wrote, On 06/03/07 17:49:
I've known a few people to use a gcc in g++ mode to craft their own
superset of C: default parameters & function overloading. If you're
going to do that, you'll need to cast your return values as well.
There are probably some penalties, and I don't expect the purist crowd
to approve, but it can make for some sweet interfaces.

That is a subset of C++ rather than a superset of C since some perfectly
valid C code will not compile in it and some will behave differently.
This does not necessarily make it wrong, after all I tend not to use all
the facilities of C.
 
R

Roland Pibinger

Why is it discouraged to explicitly typecast the void pointer returned
by malloc(); function?

For example:
{
int *p;
p = (int*)malloc(2*sizeof(int)); /*Explicit casting is done, therfore
it is said to be a bad practice*/
/*Some codes*/
}

Please, explain why.

I know two reasons why people use the cast (of course, Standard C
doesn't require the cast):
1. (already mentioned) they want their code to complile as C++, esp.
because C++ has better compile time checks
2. they use an explicit cast for all conversions (not just *alloc)
from a void* to a typed pointer to indicate that something inherently
unsafe is going on and that the conversion is deliberate, not
accidental.

Best wishes,
Roland Pibinger
 
R

Richard Bos

bluejack said:
I've known a few people to use a gcc in g++ mode to craft their own
superset of C: default parameters & function overloading. If you're
going to do that, you'll need to cast your return values as well.

No, if you're going to do that, you need a smack to the head. Choose a
language, then use it.

Richard
 
W

websnarf

Why are there multiple religions in the world? Why did the US invade
Iraq? Why are there people who think 9/11 was a conspiracy? Why do
people think its a good idea to omit the cast for malloc? Whatever
the answer is to these questions, I am sure that they are all highly
related.
I don't recommend casting the return value of malloc():

* The cast is not required in ANSI C.

But it is required by C++. Thus you are just making your code
incompatible with C++. C++ has stronger type checking in general, and
thus its a good idea to compile your C code with a C++ compiler, even
if just for checking purposes -- you can't do that if you omit these
casts.
* Casting its return value can mask a failure to #include
<stdlib.h>, which leads to undefined behavior.

I am not aware of any modern compiler for which this error isn't
already pointed out to you whether you cast or not.
* If you cast to the wrong type by accident, odd failures can
result.

If you cast to the wrong type by accident, your compiler will tell you
-- that's the point. Actually leaving off the cast means you give up
any opportunity to type check when you change variables or type
definitions. There are "find and replace" scenarios that may too
easily fail if you omit this cast.

Basically, you don't *NEED* to do the cast, but its a question of
being able to write code in a scalable and maintainable way. Putting
the cast there reduces the probability of errors in your code, and
makes it far easier to maintain.
 
R

Richard Heathfield

(e-mail address removed) said:
But it is required by C++.

Irrelevant in C programs.
Thus you are just making your code incompatible with C++.

The code will also be incompatible with Fortran, BASIC, Ada, Perl, Ook!,
Pascal, BCPL, and Python. So what?
 
D

Dave Hansen

No, if you're going to do that, you need a smack to the head. Choose a

This is a perfectly acceptable practice. No smacking required.
language, then use it.

Which is exactly what they've done: They've chosen, and are using, C+
+. Certainly it would be foolish (if not impossible) to require a
programmer to use every conceivable feature of a language in any given
program.

Of course, it's important to realize and remember that's what you've
done, if you're doing it...

Regards,

-=Dave
 
C

CBFalconer

Richard said:
(e-mail address removed) said:
.... snip ...


Irrelevant in C programs.


The code will also be incompatible with Fortran, BASIC, Ada, Perl,
Ook!, Pascal, BCPL, and Python. So what?

But will it be compatible with Modula, Euclid, Cobol, Lisp? ;-)

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
R

Richard Tobin

Irrelevant in C programs.
The code will also be incompatible with Fortran, BASIC, Ada, Perl,
Ook!, Pascal, BCPL, and Python. So what?
[/QUOTE]
But will it be compatible with Modula, Euclid, Cobol, Lisp? ;-)

It would probably compile with the PL/1 checkout compiler (which would
usually accept Fortran programs), but who knows what it would *do*.

-- Richard
 
I

Ian Collins

But it is required by C++. Thus you are just making your code
incompatible with C++. C++ has stronger type checking in general, and
thus its a good idea to compile your C code with a C++ compiler, even
if just for checking purposes -- you can't do that if you omit these
casts.
If you are going to do that, use a simple wrapper for malloc that
applies the appropriate casting rules.

Something as trivial as

#if defined __cplusplus
template <typename T> T* myMalloc( size_t n, const T* ) {
return static_cast<T*>(malloc( n * sizeof(T) ));
}
#else
#define myMalloc( n, p ) malloc( n * sizeof *p )
#endif

Will do the job.

Your sig is still broken.
 
K

Keith Thompson

Why are there multiple religions in the world? Why did the US invade
Iraq? Why are there people who think 9/11 was a conspiracy? Why do
people think its a good idea to omit the cast for malloc? Whatever
the answer is to these questions, I am sure that they are all highly
related.
[snip]

Ordinarily I would respond to this, but because of websnarf's recent
and ongoing boorish behavior (gratuitous insults and so forth), I'm
not going to participate.

Don't worry, I won't post this reminder every time he posts something
here; I just wanted to remind websnarf that his behavior has
consequences.
 
O

Old Wolf

You forgot the moon landing hoax..
Ordinarily I would respond to this, but because of websnarf's recent
and ongoing boorish behavior (gratuitous insults and so forth), I'm
not going to participate.

What amazes me is that he (apparently) manages to write code that
other people use, and seems to work!
 
K

Keith Thompson

Old Wolf said:
You forgot the moon landing hoax..


What amazes me is that he (apparently) manages to write code that
other people use, and seems to work!

I'm not particularly amazed. There isn't necessarily a strong
negative correlation between programming ability and boorishness. I'm
sorry to lose the opportunity to discuss technical issues with someone
who appears to have a decent amount of knowledge and talent, but it's
just not worth dealing with the insults. (Dan Pop sometimes annoyed
me, but at least there was generally some justification for his
"engage your brain" remarks.)
 
W

websnarf

If you are going to do that, use a simple wrapper for malloc that
applies the appropriate casting rules.

Something as trivial as

#if defined __cplusplus
template <typename T> T* myMalloc( size_t n, const T* ) {
return static_cast<T*>(malloc( n * sizeof(T) ));}

#else
#define myMalloc( n, p ) malloc( n * sizeof *p )
#endif

Will do the job.

That's great so long as sizeof *p makes some sort of sense. If you
are doing the struct hack, then this is irrelevant. Besides you can
still mis-synch the p with the variable you are assigning, so this is
not of much help. And, of course, this "alternative" doesn't
accomplish any positive affect at all (besides satisfying the neuroses
of some people in this group) versus the much simpler and safer

#define typeMalloc(type,qty) ((type *) malloc((qty)*sizeof(type)))

You can just compare it on safety, on cut and paste, simplicity, and
compatibility with C++. And the arguments against it, that are
repeated here over and over, are just blatantly false.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top