Why not cast the rerurn from malloc()?
Author |
Message |
Guy Higginso #1 / 31
|
 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 |
|
 |
Chris Engebrets #2 / 31
|
 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 |
|
 |
James #3 / 31
|
 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 Quote: >>>>>>>>>>>>> I use *SpamBeGone* <URL:http://www.internz.com/SpamBeGone/>
|
Sun, 09 Jul 2000 03:00:00 GMT |
|
 |
Kaz Kylhe #4 / 31
|
 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 |
|
 |
John Winte #5 / 31
|
 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. 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 |
|
 |
Douglas A. Gwy #6 / 31
|
 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 |
|
 |
firewin #7 / 31
|
 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 |
|
 |
Peter Seeba #8 / 31
|
 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 |
|
 |
Guy Higginso #9 / 31
|
 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 |
|
 |
Ulric Erikss #10 / 31
|
 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 |
|
 |
Ulric Erikss #11 / 31
|
 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 |
|
 |
Dann Corbi #12 / 31
|
 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 |
|
|
Page 1 of 3
|
[ 31 post ] |
|
Go to page:
[1]
[2] [3] |
|