Re: about the array



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

.



Relevant Pages

  • Re: problem with memcpy and pointers/arrays confusion - again
    ... this second method is known as an explicit conversion, or cast. ... The cast, in effect, tells the compiler: ... the malloc function. ... function taking a size_t as a parameter and returning a void pointer (i.e. ...
    (comp.lang.c)
  • Re: what will happen after i use free()???
    ... Inserting a cast before malloc is not needed, ... 56 bits while int is only 48 bits. ... So casting that value requires some ... Use cast only if you are absolutely sure that yor really needs the ...
    (comp.lang.c)
  • Re: Reading a string of unknown size
    ... "Don't cast return value of malloc() in C. ... It is entirely possible for an int to be returned by a ... function using a different method than that used to return a pointer. ...
    (comp.lang.c)
  • Re: about the array
    ... I guess the bottom line is - if the cast isn't necessary, why do it, esp. ... the compiler should issue a diagnostic - gcc gives: ... it], and screw up, e.g., without the declaration, the compiler *should* ... maybe the int taken by the ...
    (comp.lang.c)
  • Re: problems with dynamic allocation in an ellipses function
    ... and the compiler assumes that it returns an int. ... But malloc returns void*, ... Then you cast it to a pointer, and you are now corrupt - only half of the ...
    (comp.lang.c)