Re: about the array
- From: "Peter Nilsson" <airia@xxxxxxxxxxx>
- Date: 5 Mar 2006 14:53:37 -0800
pemo wrote:
Taking the reasons from the webpage cited ...[i.e. <http://benpfaff.org/writings/clc/malloc-cast.html>]
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
Quite often in my code, the _only_ functions being used from <stdlib.h>
are malloc and free. I don't always use the NULL macro, but when I do
it's often available from other headers (e.g. <stdio.h>.)
A call to an implicitly declared free() does not require a diagnostic.
[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.
It isn't mandatory in C90! That's the whole point!!
Personally, I think it's fair to say that most compiler writers
appreciate the problems with using undeclared functions, so most
compilers will issue a diagnostic, but the C90 language itself
does not _require_ compilers to do so. [And there are plenty of
old compilers that won't issue a warning, let alone an error.]
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);
That requires a diagnostic too because you're assigning an integer
value to a pointer without a cast (from int to pointer.) To be honest,
I'm not exactly sure what Ben is talking about in point 3.
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'.
Yes, it's a _required_ diagnostic, so _every_ conforming compiler
must issue a warning or error.
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);
It is not legal since malloc returns a void *, not an int. The code
is no different to...
/* no #include <stdlib.h> */
int malloc();
void foo()
{
/* UB since malloc has the wrong signature */
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 *.
Indeed. It may be the wrong size, or may be in a completely different
register. [For example, Motorola's 68000 series has both data and
address registers. Many implementations will return an int in register
D0, and a pointer in register A0. Without a valid declaration, a
compiler may assume malloc's return value is in D0, instead of A0.
Thus, it may use a garbage value totally unrelated to the malloc()
call.]
*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.
I agree, but the issue is not about what _most_ compilers will or
won't do. [Or what most programmers _should_ be doing: turn on the
warning if available.] It's about whether compilers are _required_
to issue diagnostics, be they warnings or errors.
<snip>
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"
Yes, but you clearly don't understand _why_ the compiler is
_required_ to issue the diagnostic. It's to do with assignment.
The situation is identical to...
int *p = 0xFFFE;
I don't think that even the regulars of clc would accuse newbies of
commonly casting malloc to int.
How about if you do this - where you're casting the return type to
the lvalue type ...
int p = (int)malloc(10);
This doesn't require a diagnostic, but you now have implementation
defined behaviour (if you include a prototype for malloc.) Any
subsequent conversion of that int to a void *, e.g. ...
void *vp = (void *) p;
....need _not_ yield the original pointer returned by malloc(),
irrespective of whether int is wider than void * or not.
--
Peter
.
- Prev by Date: Re: what is the difference between getch() & getche()
- Next by Date: Re: two-dimensional array
- Previous by thread: Unknown function
- Next by thread: 'restrict' in plain English?
- Index(es):
Relevant Pages
|