Rajesh said:
Hello Peter,
Thanks for the explanations.
Can u put some light on :
"Casting its return value can mask a failure to #include <stdlib.h>,
which leads to undefined behavior"
What type of failure is it?
"C99 requires all functions to be declared before they are called."
Does C89 doesn't requires that?
Rajesh
What type of failure is it?
Disclaimer:
I guess the bottom line is - if the cast isn't necessary, why do it, esp. if
there exists some compiler, in the set of all compilers, that will screw up
if you do!
---
Taking the reasons from the webpage cited ...
1- The cast is not required in ANSI C.
2- Casting its return value can mask a failure to #include <stdlib.h>, which
leads to undefined behavior. As C99 slows[sic] becomes more popular, this
will become less of an issue, because C99 requires all functions to be
declared before they are called.
3- If you cast to the wrong type by accident, odd failures can result. This
is especially true if <stdlib.h> is not #included, as above, but alignment
can still cause trouble on particularly odd systems.
1. True - see the disclaimer.
2. IMHO, not likely ... in so far that if you used another function declared
in stdlib, you'd most likely get a warning about *its* use [unless it obeys
the default rules - in which case it's ok] - even if you somehow managed to
escape such a warning about misusing malloc. Esp. not likely to be an issue
when it's mandatory to have declared a function before using it of course.
3.
I think the argument is that *if* you cast wrongly, you could end up in
trouble. E.g., say you had this ...
char * p = (char)malloc(10);
Maybe p will only get CHAR_BIT's worth of data assigned to it [which you
probably don't want right]?
By including stdlib, the compiler should issue a diagnostic - gcc gives:
'cast from pointer to integer of different size'.
However, if you cast \correctly\, but omit stdlib, then the compiler may
make assumptions about what malloc \is\ [how to call/return a value from
it], and screw up, e.g., without the declaration, the compiler *should*
consider malloc to have external linkage, take an unknown set of arguments,
and return an int. So, if you have this usage - which is legal according to
those rules ...
void * p = (void *)malloc(10);
Well, maybe the int taken [off the stack or wherever it comes from] by the
compiler isn't *right* for a void *.
*However*, that all said, in my experience, compilers will typically tell
you that you haven't declared malloc before using it - with/without the
cast. For example, if you have either of these in gcc code ...
char * p = (char *)malloc(10);
char * p = (char)malloc(10);
You'll see warnings like this ...
"implicit declaration of function 'malloc'"
"incompatible implicit declaration of built-in function 'malloc'"
"cast from pointer to integer of different size"
"assignment makes pointer from integer without a cast"
So, if you then include stdlib, the second of those usages [the cast to
(char)] will once again cause gcc to issue the pointer to integer warning
again.
IMHO, most modern compilers would catch misuses, even if the sizes of a void
* and the lvalue are the same - but of diferent types. For example:
If an int is the same size as a void *, and you have this, and no #include
<stdlib.h> ...
int * p = (int)malloc(10);
Most compilers will complain along these lines ...
"assignment makes pointer from integer without a cast"
How about if you do this - where you're casting the return type to the
lvalue type ...
int p = (int)malloc(10);
"implicit declaration of function 'malloc'"
"incompatible implicit declaration of built-in function 'malloc'"
Re gcc, the 'built-in' part of this is interesting - because gcc obviously
*knows* about malloc, as demonstrated by, say, doing this [With *no* headers
included]:
int p;
p = (int)malloc();
gcc says:
"too few arguments to function 'malloc'"
So, switching to another - less smart - compiler, I get this:
'malloc' undefined; assuming extern returning int
And - to another - I get this :
Missing prototype for 'malloc'
So, in summary - IMHO
1. True - don't cast.
2. Hmmm.
3. if there exists some compiler, in the set of ... You can bet there is
more than one of course!