|
| Rajesh wrote:
> 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!
--
==============
Not a pedant
==============
|
|