Why not cast the rerurn from malloc()? 
Author Message
 Why not cast the rerurn from malloc()?

Hello everyone,

I'm confused.  I was always taught that since malloc() et al returned a
void pointer it should be cast to the appropriate data type explicitly.

For example,

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  float *pf;  /* Pointer to float */

  if ((pf = (float*)malloc(sizeof(float))) != NULL)
  /*         ^^^^^^                              */
  {
    printf("Couldn't allocate memory\n"):
    exit(1);
  }

  /* Do some stuff */

  free(pf);
  return 0;

Quote:
}

was the way things should be done, with the explicit (float*) cast.
I've been reading a few postings on this group and I see people saying
that the (float*) cast should not be used.
I looked at the C FAQ and the only references to this I found were
questions 7.6 and 7.7 which just confirmed that yes, modern practice
discourages the use of the cast. They also said to make sure that the
stdlib.h header file was included (as that is where malloc lives) which
I understand but I still don't understand why the cast is not
needed/discouraged. If anyone could offer an explanation I'd be
grateful.

Thanks in advance,

Guy Higginson



Sun, 09 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?

|> I'm confused.  I was always taught that since malloc() et al returned a
|> void pointer it should be cast to the appropriate data type explicitly.

It is precisely *because* malloc() returns a (void *) that it does not
*need* to be casted.  The C language guarantees that a void pointer can
convert directly into any other object pointer of arbitrary type, and
vice versa.  This allowance comes in useful elsewhere in the standard
library where generic pointers are needed (for example, memset().)

The practice of casting the return value of *alloc() is not something
that has been made popular by modern, standard C.  It was generally
required in pre-standard C (which had no generic pointer type) where
malloc was typically declared as returning (char *).  In K&R C all
pointer conversions of this nature require an explicit cast.  This
practice has carried over, for better or worse, into modern C where
it is useless (at best.)

|> I've been reading a few postings on this group and I see people saying
|> that the (float*) cast should not be used.

Indeed it shouldn't.

|> I looked at the C FAQ and the only references to this I found were
|> questions 7.6 and 7.7 which just confirmed that yes, modern practice
|> discourages the use of the cast. They also said to make sure that the
|> stdlib.h header file was included (as that is where malloc lives) which
|> I understand but I still don't understand why the cast is not
|> needed/discouraged.

If <stdlib.h> has been #included and malloc() has been properly
prototyped as returning (void *), the conversion is handled auto-
matically by the language.  No cast is needed.  Assuming that
malloc() is properly prototyped, a cast does not hurt things, but
it buys you nothing and causes problems when <stdlib.h> is absent.

Regards,

--
Chris Engebretson - Raytheon STX Corporation | Ph#: (605)594-6829
USGS EROS Data Center, Sioux Falls, SD 57198 | Fax: (605)594-6940

Opinions are not those of  Raytheon Systems Company  or the USGS.



Sun, 09 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?

On Wed, 21 Jan 1998 18:30:52 +0000, Guy Higginson

Quote:

>Hello everyone,

>I'm confused.  I was always taught that since malloc() et al returned a
>void pointer it should be cast to the appropriate data type explicitly.

>#include <stdlib.h>

>int main(void)
>{
>  float *pf;  /* Pointer to float */
>  pf = (float*)malloc(sizeof(float))
>  /*    ^^^^^^                              */
>  free(pf);
>  return 0;
>}

>was the way things should be done, with the explicit (float*) cast.
>I've been reading a few postings on this group and I see people saying
>that the (float*) cast should not be used.

This is mostly a matter of style.  If you turn on full warnings, you
might get a warning about using malloc with no prototype in scope, which
should cause the sound of KLAXON's to go off inside your head.

Quote:
>I looked at the C FAQ and the only references to this I found were
>questions 7.6 and 7.7 which just confirmed that yes, modern practice
>discourages the use of the cast. They also said to make sure that the
>stdlib.h header file was included (as that is where malloc lives) which
>I understand but I still don't understand why the cast is not
>needed/discouraged. If anyone could offer an explanation I'd be
>grateful.

Standard C does not require a cast for assignments from a (void *) type to
some other pointer type.  The "narrowing" is done for you.  Since malloc()
returns a `void *', no cast is required.

As has been repeated here before, an explicit cast is discouraged,
because if there is not a prototype in scope, malloc() is assumed to be
a function returning an `int'.  Without a prototype in scope, the cast
will hide the fact that malloc() has returned an `int' rather than a
`void *', and your compiler will not have had the opportunity to warn
you about the mistake.  If the size of an `int' is not the same size as
a `void *' on your machine, then `bad things will happen'.  If it does
happen to work on your machine, then you will become terribly confused
when the identical code does not work on someone else's machine.

On the other hand, the (float*) cast is a necessity if you are trying
to maintain code compatibility with C++.  But, C++ forbids calling a
function that does not have a prototype in scope.

--

http://www.cs.wustl.edu/~jxh/        Washington University in Saint Louis

- Show quoted text -

Quote:
>>>>>>>>>>>>> I use *SpamBeGone* <URL:http://www.internz.com/SpamBeGone/>



Sun, 09 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?



Quote:
>Hello everyone,

>I'm confused.  I was always taught that since malloc() et al returned a
>void pointer it should be cast to the appropriate data type explicitly.

When ANSI C introduced pointers to void, it blessed them with special
properties which make casting unnecessary.

Casts to and from void * are necessary only for compatibility with C++,
which requires such casts in some contexts.

Quote:
>For example,

>#include <stdio.h>
>#include <stdlib.h>

>int main(void)
>{
>  float *pf;  /* Pointer to float */

>  if ((pf = (float*)malloc(sizeof(float))) != NULL)

This is unnecessary and ugly. The whole reason why void pointers were
introduced in ANSI C was to eliminate such ugliness as:

        T *t = (T *) malloc(sizeof *t);

and

        memcpy((char *) &dest_obj, (char *) &src_obj, sizeof dest_obj);

allowing you to simply write

        T *t = malloc(sizeof *t);
        memcpy(&dest_obj, &src_obj, sizeof dest_obj);

The nice thing about void pointers is that the mechanism they replace
is too powerful. Once you cast to (char *), you suppress most of the
constraint checking mechanisms---any scalar type can be cast to a (char *).

But only pointer-to-object types can convert to and from (void *) without a
cast!  Thus the power of the conversion is somewhat intermediate; it
is not as powerful as a cast.  If you try to convert something other than a
pointer to object to a void * or vice versa, you violate a constraint, and get
a diagnostic message. If you train yourself to avoid writing unnecessary
casts, you can benefit from this constraint safety net.

Quote:
>was the way things should be done, with the explicit (float*) cast.
>I've been reading a few postings on this group and I see people saying
>that the (float*) cast should not be used.

The cast doesn't do anything, because the conversion will happen anyway.
If there is something wrong with the conversion---such as the right
hand side is an integer rather than a pointer---the cast will hide
such an error. The implicit conversion to void * will catch the error
because it only works for pointers.


Sun, 09 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?


Quote:

>On Wed, 21 Jan 1998 18:30:52 +0000, Guy Higginson

>>Hello everyone,

>>I'm confused.  I was always taught that since malloc() et al returned a
>>void pointer it should be cast to the appropriate data type explicitly.

>>#include <stdlib.h>

>>int main(void)
>>{
>>  float *pf;  /* Pointer to float */
>>  pf = (float*)malloc(sizeof(float))
>>  /*    ^^^^^^                              */
>>  free(pf);
>>  return 0;
>>}

>>was the way things should be done, with the explicit (float*) cast.
>>I've been reading a few postings on this group and I see people saying
>>that the (float*) cast should not be used.

>This is mostly a matter of style.  If you turn on full warnings, you
>might get a warning about using malloc with no prototype in scope, which
>should cause the sound of KLAXON's to go off inside your head.

If you get a warning about there being no prototype for malloc() in
scope then your code is broken, pure and simple.  No amount of casting
will cure it.

This is the reason for advising against casting the result of malloc().
If you cast the result of malloc then *some* compilers will still detect
the error of not including stdlib.h.  If you don't cast the result
of malloc then *all* compilers will detect it.

Quote:
>>I looked at the C FAQ and the only references to this I found were
>>questions 7.6 and 7.7 which just confirmed that yes, modern practice
>>discourages the use of the cast. They also said to make sure that the
>>stdlib.h header file was included (as that is where malloc lives) which
>>I understand but I still don't understand why the cast is not
>>needed/discouraged. If anyone could offer an explanation I'd be
>>grateful.

See above.

- Show quoted text -

Quote:
>Standard C does not require a cast for assignments from a (void *) type to
>some other pointer type.  The "narrowing" is done for you.  Since malloc()
>returns a `void *', no cast is required.

>As has been repeated here before, an explicit cast is discouraged,
>because if there is not a prototype in scope, malloc() is assumed to be
>a function returning an `int'.  Without a prototype in scope, the cast
>will hide the fact that malloc() has returned an `int' rather than a
>`void *', and your compiler will not have had the opportunity to warn
>you about the mistake.  If the size of an `int' is not the same size as
>a `void *' on your machine, then `bad things will happen'.  If it does
>happen to work on your machine, then you will become terribly confused
>when the identical code does not work on someone else's machine.

>On the other hand, the (float*) cast is a necessity if you are trying
>to maintain code compatibility with C++.  But, C++ forbids calling a
>function that does not have a prototype in scope.

OTOOH, if you're writing in C++ you shouldn't be using malloc() anyway.

John
--
John Winters.  Wallingford, Oxon, England.

The Linux Emporium - a source for Linux CDs in the UK
See <http://www.polo.demon.co.uk/emporium.html>



Sun, 09 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?

Quote:

> I'm confused.  I was always taught that since malloc() et al returned a
> void pointer it should be cast to the appropriate data type explicitly.

Funny, you don't *sound* confused.

Quote:
> I've been reading a few postings on this group and I see people saying
> that the (float*) cast should not be used.

Oh, so now I understand your confusion.
If anyone said that the cast should not be used, they were wrong.

If a prototype is in scope (as it would be if you #include <stdlib.h>,
which is only available since the C standard was issued), then the
cast isn't necessary, because the pointer-to-void is automatically
converted as necessaru.

In pre-ANSI C environments, the cast is a good idea, and it doesn't
hurt in any environment.  In fact, it documents the fact that you
realize there is a conversion going on at that point.



Sun, 09 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?

Quote:

> I'm confused.  I was always taught that since malloc() et al returned a
> void pointer it should be cast to the appropriate data type explicitly.

Your teacher was either ignorant, or you found yourself in a C++ class by
some horribly, hopefully correctable, error. 'void *' is always implicitly
converted to the correct type in C.

[snip]

Quote:
>   pf = (float*)malloc(sizeof(float));

[snip]

Quote:
> was the way things should be done, with the explicit (float*) cast.
> I've been reading a few postings on this group and I see people saying
> that the (float*) cast should not be used.

That is correct.

Quote:
> I looked at the C FAQ and the only references to this I found were
> questions 7.6 and 7.7 which just confirmed that yes, modern practice
> discourages the use of the cast. They also said to make sure that the
> stdlib.h header file was included (as that is where malloc lives) which
> I understand but I still don't understand why the cast is not
> needed/discouraged. If anyone could offer an explanation I'd be
> grateful.

If <stdlib.h> is not #included, the call:

        pf = (float *)malloc(sizeof(float));

introduces an implicit type for malloc(), which is:

        int malloc(size_t);

which is incorrect. Were the cast not there, you would be attempting to
assign an 'int' value to a 'pointer to float,' which is a constraint
violation.

--
The FAQ, like the C standard (and, for that matter, the Bible and the US
Constitution) is often used as an authority by clueless people who don't
seem to have read it, at least not with any level of comprehension.



Sun, 09 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?


Quote:
>> I've been reading a few postings on this group and I see people saying
>> that the (float*) cast should not be used.
>Oh, so now I understand your confusion.
>If anyone said that the cast should not be used, they were wrong.

No.  They disagreed with you on a matter of style.

Quote:
>If a prototype is in scope (as it would be if you #include <stdlib.h>,
>which is only available since the C standard was issued), then the
>cast isn't necessary, because the pointer-to-void is automatically
>converted as necessaru.

Yes.

Quote:
>In pre-ANSI C environments, the cast is a good idea, and it doesn't
>hurt in any environment.  In fact, it documents the fact that you
>realize there is a conversion going on at that point.

It can hurt if you omit <stdlib.h> by accident, and it hurts because
it implies that you think there's a non-implicit conversion that you
care about happening.

Casting from (void *) is best left only to situations where it matters,
i.e., variadic function arguments, and the like.  Otherwise, it's better
to leave superfluous casts out.

Portabilty to pre-ANSI C environments is not a big concern for many of us
these days.

-s
--

All rights reserved.  Boycott Spamazon!  End Spam.  C and Unix wizard -
send mail for help, or send money for a consultation.  Visit my new ISP
<URL:http://www.plethora.net/> --- More Net, Less Spam!  Plethora . Net



Mon, 10 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?

Many thanks for all your explanations on the casting malloc() question.
I understand now. Thanks also to Dann Corbit who replied by e-mail.

Regards,

Guy Higginson



Mon, 10 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?


Quote:

>If you get a warning about there being no prototype for malloc() in
>scope then your code is broken, pure and simple.  No amount of casting
>will cure it.

>This is the reason for advising against casting the result of malloc().
>If you cast the result of malloc then *some* compilers will still detect
>the error of not including stdlib.h.  If you don't cast the result
>of malloc then *all* compilers will detect it.

And the list of compilers which won't detect it is...?

This issue belongs in the same category as

        if ('\0' = *p)

i.e. a hack to detect one instance of an error is promoted to religion,
without actually solving anything.

The proper solution to finding missing prototypes is to let the
compiler produce diagnostics for missing prototypes.

Ulric
--
Another opinion presented as fact.



Mon, 10 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?


Quote:


>> I've been reading a few postings on this group and I see people saying
>> that the (float*) cast should not be used.

>That is correct.

"The (float *) cast need not be used" is correct.
"The (float *) cast should not be used" is an opinion.

There are valid reasons not to cast: it reduces wear on the fingers
and Kaz thinks the cast is ugly.

There are also valid reasons to cast: compatibility with the
mythical C/C++ language, and it makes the conversion explicit
to the reader.

None of these reasons are particularly strong.

The discussion the other day springs to mind where one program
overflowing with comments was followed up by one with no comments
at all, which was in turn followed up by one with *some* comments
and, not to forget, *improved whitespace*.

(I bet I'll be the lone fool on this side of the fence as usual,
but that's half the fun.)

Ulric
--
Another opinion presented as fact.



Mon, 10 Jul 2000 03:00:00 GMT  
 Why not cast the rerurn from malloc()?

[snip]

Quote:
>There are valid reasons not to cast: it reduces wear on the fingers
>and Kaz thinks the cast is ugly.

>There are also valid reasons to cast: compatibility with the
>mythical C/C++ language, and it makes the conversion explicit
>to the reader.

>None of these reasons are particularly strong.

>The discussion the other day springs to mind where one program
>overflowing with comments was followed up by one with no comments
>at all, which was in turn followed up by one with *some* comments
>and, not to forget, *improved whitespace*.

>(I bet I'll be the lone fool on this side of the fence as usual,
>but that's half the fun.)

In an earlier thread, this subject was hashed to death.  I feel that
compelling arguments were made on both sides.  I will agree with your
assertion, due to the following:
Every current C compiler in my possession complains when a prototype is
missing.  Now, I don't know for sure if this is _required_ by the language
specification, but for all practical purposes it happens.  So when I type:

#include <stdio.h>
char *foo(size_t nbytes)
{
   return (char *) malloc(nbytes); /* IT'S JUST AN EXAMPLE -- OK! */

Quote:
}

And some loony changes my code in the project to:

/* I often forget to end comments...
#include <stdio.h>
/* This function is pretty dull... */
char *foo(size_t nbytes)
{
   return (char *) malloc(nbytes); /* IT'S JUST AN EXAMPLE -- OK! */

Quote:
}

I will get a warning about no prototype in scope for malloc(). [And possibly
one about possible nested comments].  So the upshot is, I get a warning either
way.

So I guess I am siding with Ulric -- though I still do not like the casts for
C only projects.



Mon, 10 Jul 2000 03:00:00 GMT  
 
 [ 31 post ]  Go to page: [1] [2] [3]

 Relevant Pages 

1. Why not cast malloc?

2. malloc: to cast or not to cast

3. Why cast malloc's return?

4. why not typecast malloc() o/p??????

5. Linked List -- why not just "malloc()"?

6. Q: Why IMalloc not malloc or HeapAlloc?

7. to cast or not to cast?

8. Discarded Function Values (To Cast or Not to Cast)

9. When is a cast not a cast?

10. to malloc() or not to malloc(), that is the question

11. casting malloc question.

12. casting malloc question.

 

 
Powered by phpBB® Forum Software