For Programmers: Free Programming Magazines  


Home > Archive > C > February 2006 > Re: about the array









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Re: about the array
pemo

2006-02-28, 7:55 am

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
==============


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com