Casting return of malloc

Y

ytrama

Hi,
I have read in one of old posting that don't cast of pointer which
is returned by the malloc. I would like to know the reason.

Thanks in advance,
YTR
 
D

Dave Vandervies

Hi,
I have read in one of old posting that don't cast of pointer which
is returned by the malloc. I would like to know the reason.

It isn't necessary, and it hides errors. Why do the extra typing for
something with a negative benefit?


dave
 
J

Joona I Palaste

Hi,
I have read in one of old posting that don't cast of pointer which
is returned by the malloc. I would like to know the reason.

It won't fix anything, but it may make the compiler think problems are
fixed when they really aren't.

Longer explanation:
Without a proper prototype for malloc(), the compiler thinks it returns
int. Thus, when malloc creates a void* value and returns it, the
compiler implicitly converts it to int. The value is *already* broken at
this case, so no amount of casting it to anything will help. However,
if you cast it to a pointer type, the compiler will *think* you know
what you're doing, and omit a warning. Thus you get broken code that
looks like working code.
 
E

E. Robert Tisdale

Joona said:
ytrama said:
I have read in one old posting that
[you shouldn't] cast [the] pointer which is returned by malloc.
I would like to know the reason.

It won't fix anything
but it may make the compiler think problems are fixed
when they really aren't.

Longer explanation:
Without a proper prototype for malloc(),
the compiler thinks it returns int.
Thus, when malloc creates a void* value and returns it,
the compiler implicitly converts it to int.
The value is *already* broken at this case,
so no amount of casting it to anything will help.
However, if you cast it to a pointer type,
the compiler will *think* you know what you're doing and omit a warning.
Thus you get broken code that looks like working code.

That's *not* true.
> cat f.c
void f(void) {
char* p = (char*)malloc(128);
for (size_t j = 0; j < 128; ++j)
p[j] = j;
}
> gcc -Wall -std=c99 -pedantic -c f.c
f.c: In function `f':
f.c:2: warning: implicit declaration of function `malloc'
f.c:3: error: `size_t' undeclared (first use in this function)
f.c:3: error: (Each undeclared identifier is reported only once
f.c:3: error: for each function it appears in.)
f.c:3: error: parse error before "j"
f.c:3: error: `j' undeclared (first use in this function)
f.c:3: error: parse error before ')' token
f.c: At top level:
f.c:2: warning: unused variable `p'

The compiler gives ample diagnostics
should you fail to #include <stdlib.h>
which defines malloc(size_t) and size_t.

> cat f.cc
#include <stdlib.h>

void f(void) {
char* p = malloc(128);
for (size_t j = 0; j < 128; ++j)
p[j] = j;
}
> g++ -Wall -ansi -pedantic -c f.cc
f.cc: In function `void f()':
f.cc:4: error: invalid conversion from `void*' to `char*'
 
B

Ben Pfaff

I have read in one of old posting that don't cast of pointer which
is returned by the malloc. I would like to know the reason.

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.

Some others do disagree, such as P.J. Plauger (see article
<[email protected]>).
 
C

CBFalconer

Ben said:
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.

Some others do disagree, such as P.J. Plauger (see article
<[email protected]>).

and E. Robert Trollsdale. What a combination! It reminds me of
the first term in the process of summing an arithmetic progression,
i.e. (1 + N) + (2 + N-1) ...
 
F

Flash Gordon

E. Robert Tisdale said:
Joona said:
ytrama said:
I have read in one old posting that
[you shouldn't] cast [the] pointer which is returned by malloc.
I would like to know the reason.


It won't fix anything
but it may make the compiler think problems are fixed
when they really aren't.

Longer explanation:
Without a proper prototype for malloc(),
the compiler thinks it returns int.
Thus, when malloc creates a void* value and returns it,
the compiler implicitly converts it to int. The value is *already*
broken at this case, so no amount of casting it to anything will help.
However, if you cast it to a pointer type,
the compiler will *think* you know what you're doing and omit a warning.
Thus you get broken code that looks like working code.

That's *not* true.
void f(void) {
char* p = (char*)malloc(128);
for (size_t j = 0; j < 128; ++j)
p[j] = j;
}
gcc -Wall -std=c99 -pedantic -c f.c
f.c: In function `f':

The compiler gives ample diagnostics
should you fail to #include <stdlib.h>
which defines malloc(size_t) and size_t.

There are more compilers than are dreamed of in your philosophy.

Or to be more explicit, why rely on the fact that *some* compilers will
warn when by doing less typing you can ensure that *all* C compilers
will produce a diagnostic.
On good reason for casting malloc(int) to the desired type
is so you can compile with a C++ compiler:

Not a valid reason (except for whatsisname, sorry, I can't remember it)
who has a commercial reason.

The best way to integrate C code with any other language is to compile
it as C and use whatever mechanism the other language provides for the
integration. If you can point me at any C++ compiler vendor who does not
also provide a C compiler that its code will link against I might
reconsider, but such would be extremely rare.
 
M

Mike Wahler

Hi,
I have read in one of old posting that don't cast of pointer which
is returned by the malloc. I would like to know the reason.

You've got it backwards. Before writing any cast,
find a defensible reason to do so. There is no
such reason when assigning a 'void*' (which is
the type returned by 'malloc()') value to another
(object) pointer type.

-Mike
 
K

Keith Thompson

Ben Pfaff said:
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.

Some C90 compilers, and all conforming C99 compilers, will warn about
this anyway. (That's certainly not an argument in favor of casting,
of course.)
* If you cast to the wrong type by accident, odd failures can
result.

Some others do disagree, such as P.J. Plauger (see article
<[email protected]>).

I don't know that he necessarily disagrees; he just happens to work in
an unusual environment where casting the result of malloc() makes
sense. I don't think he would argue that *everyone* should cast the
result of malloc(). (I can't find that message-id on Google; are you
sure it's correct?)
 
B

Ben Pfaff

Keith Thompson said:
Some C90 compilers, and all conforming C99 compilers, will warn about
this anyway. (That's certainly not an argument in favor of casting,
of course.)

Often I give this advice to novices, who in many cases seem to
believe that the proper way to deal with warnings is to disable
them. Experts, of course, know better, but experts are not in
need of advice from me.
I don't know that he necessarily disagrees; he just happens to work in
an unusual environment where casting the result of malloc() makes
sense. I don't think he would argue that *everyone* should cast the
result of malloc().

I think you're right. I will rephrase my advice for future
posts. How about this:

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. 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 can't find that message-id on Google; are you sure it's
correct?)

I can't be sure, if it's not available now, but I cut-and-paste
it instead of trying to retype it, so I don't know what would
have gone wrong.
 
M

Michael Mair

E. Robert Tisdale said:
Joona said:
ytrama said:
I have read in one old posting that
[you shouldn't] cast [the] pointer which is returned by malloc.
I would like to know the reason.


It won't fix anything
but it may make the compiler think problems are fixed
when they really aren't.

Longer explanation:
Without a proper prototype for malloc(),
the compiler thinks it returns int.
Thus, when malloc creates a void* value and returns it,
the compiler implicitly converts it to int. The value is *already*
broken at this case, so no amount of casting it to anything will help.
However, if you cast it to a pointer type,
the compiler will *think* you know what you're doing and omit a warning.
Thus you get broken code that looks like working code.


That's *not* true.
use of size_t without <stdio.h> or <stdlib.h> requires
#include <stddef.h>

Your example is broken.
void f(void) {
char* p = (char*)malloc(128);
for (size_t j = 0; j < 128; ++j)
p[j] = j;
}
gcc -Wall -std=c99 -pedantic -c f.c
f.c: In function `f':
f.c:2: warning: implicit declaration of function `malloc'
f.c:3: error: `size_t' undeclared (first use in this function)
f.c:3: error: (Each undeclared identifier is reported only once
f.c:3: error: for each function it appears in.)
f.c:3: error: parse error before "j"
f.c:3: error: `j' undeclared (first use in this function)
f.c:3: error: parse error before ')' token
f.c: At top level:
f.c:2: warning: unused variable `p'

The compiler gives ample diagnostics
should you fail to #include <stdlib.h>
which defines malloc(size_t) and size_t.

All of your errors and one warning come from your failure to #include
<stddef.h>, only one warning from the use of malloc() without prototype
in scope. Many people unfortunately ignore warnings.

On good reason for casting malloc(int) to the desired type
is so you can compile with a C++ compiler:

[snip]

This is comp.lang.c; C++ compilers cannot compile many
standard conforming C programs as C and C++ are different
languages.
Apart from a select few exceptions, mixing of C and C++
is unnecessary and unnecessarily dangerous. C++ specified
an interface to C for a very good reason.


-Michael
 
E

E. Robert Tisdale

Michael said:
This is comp.lang.c;
C++ compilers cannot compile many standard conforming C programs

C++ compiler can compile *most* standard conforming C programs.
as C and C++ are different languages.

C++ contains almost all of C.
Apart from a select few exceptions,
mixing of C and C++ is unnecessary and unnecessarily dangerous.

Who said anything about "mixing" C and C++?
When I compile C programs with my C++ compiler, they *are* C++ programs.
C++ specified an interface to C for a very good reason.

C++ does *not* specify an interface to C.
It specifies extern "C" to *help* with linkage.
The C++ compiler must be compatible with the C compiler
which might be accomplished
if, for example, the C++ compiler conforms with
the C Application Binary Interface (ABI)
for the target platform.
 
J

Joona I Palaste

That's no email address. It's a message ID. To be specific it's the
message id of the following message:

Frankly, I believe Trollsdale knew that. I don't think anyone would be
stupid enough to think a string of text with something so unreadable
(even including a $ sign, no less) before the "@" sign was an e-mail
address, even though the mere sight of the "@" sign screams "e-mail
address!!!" to 99.999% of the world's literate population.
It's just that Trollsdale is being Trollsdale again. He pretends to be
stupider than he really is, hoping it will annoy people.
 
E

E. Robert Tisdale

Joona said:
He pretends to be stupider than he really is,

I'm not pretending. ;-)

I'm as stupid as I appear to be.

But I'd like to believe that you are pretending.
 
I

infobahn

E. Robert Tisdale said:
C++ compiler can compile *most* standard conforming C programs.

It generally fails to compile mine.
C++ contains almost all of C.

Not enough. More to the point, too much extra.
Who said anything about "mixing" C and C++?
When I compile C programs with my C++ compiler, they *are* C++ programs.

Then please feel free to discuss them in comp.lang.c++


<snip>
 
D

Dave Vandervies

E. Robert Tisdale said:
On good reason for casting malloc(int) to the desired type
is so you can compile with a C++ compiler:

And if you do this:

#define BEGIN {
#define END }
#define IF if(
#define THEN )

you can write even worse code that you can compile with a Pascal
compiler too!

(Wait, you've suggested doing this before, haven't you? Forget I said
anything...)


dave
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top