[comp.sys.amiga] malloc

dillon@CORY.BERKELEY.EDU (Matt Dillon) (04/14/88)

>main()
>{
>	struct def *head;
>
>	head = (struct def *) malloc(sizeof(struct def));
>
>Any help on how to get rid of this warning, would help.

	Because you ARE casting from an int to  a pointer... you need to
declare malloc as returning a pointer:

extern char *malloc();

	Or, if you don't want to bother with a cast, you can:

extern void *malloc();


Leo has kind of set a convention of making a lot of intuition funcs() return
void -->  void *OpenScreen().  Then in the code he has: s=OpenScreen(&sdef);
He might have a cast.  Anyways, why would you do this?  The compilier should
issue an error, you can't return values from a void func()? I understand
it has to do with 16 bit ints and what not.  Comments?

	He's returning a 'void *' ... not a void, but a pointer to a void.
That's an ANSI standard, I believe, meaning "pointer to anything".  It's
useful for things like AllocMem() and malloc(), but Leo's just being 
lazy if he's using it for OpenScreen().

				-Matt

dillon@CORY.BERKELEY.EDU (Matt Dillon) (04/16/88)

>	You may accuse me of being lazy, but it works, and I think it makes
>my code more readable.  Can anyone think of a compelling reason why I should
>explicitly cast stuff?
>
>_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
>Leo L. Schwab -- The Guy in The Cape  ihnp4!pacbell -\

	Oh, not *that* bad, Leo.  I use (void *) to.  What I meant was that
for some things, like OpenScreen(), which returns an explicit Screen structure,
declaring it:

extern Struct Screen *OpenScreen();
	or
extern SCR *OpenScreen();	(I use typedefs all the time)

	Means that you still do not need casts in the code.  BUT, for things
like GetMsg(), AllocMem(), malloc(), GetHead(), etc... I usually declare 
those (void *)  Since they can returns just about anything (e.g. my linked
list is a custom structure with a Node at the front).

					-Matt

dsill@nswc-oas.arpa (Dave Sill) (04/16/88)

Leo 'Bols Ewhac' Schwab <well!ewhac> writes:
>In article <315@unicom.UUCP> mille_g@unicom.UUCP (Shane 'spin1' Miller) writes:
>>Leo has kind of set a convention of making a lot of intuition funcs() return
>>void -->  void *OpenScreen().  Then in the code he has: s=OpenScreen(&sdef);
>>...
>... I'm casting them to return a void * (pointer to
	 -------
>nothing), which is a generic pointer which can be assigned to any other kind
>of pointer.

You aren't casting them, you're *declaring* them.

Draft proposed ANSI C (section 3.2.2.3 Oct. '86):
"A pointer to `void' may be converted to a pointer to an object of any
type.  A pointer to an object of any type may be converted to a
pointer to `void' and back again; the result shall compare equal to
the original."

That's not exactly a "generic pointer".  It more like a box that can
hold any pointer.

>	You may accuse me of being lazy, but it works, and I think it makes
>my code more readable.

I don't think it improves readability.  It seems to me you have the
choice of doing either:
	Glorp *GetGlorp();
	Glorp a_glorp;

	a_glorp = GetGlorp();
or
	void *GetGlorp();
	Glorp a_glorp;

	a_glorp = GetGlorp();

In my opinion, the first is more readable because GetGlorp() returns a
pointer to a Glorp(), not a pointer to nothingness.  Additionally, the
former works on non-ANSI compilers.

>  Can anyone think of a compelling reason why I should
>explicitly [declare] stuff?

Well, for one thing, `void *' only works with so-called
ANSI-compatible compilers.  Another problem is that you are
redeclaring the Intuition functions, and the dpANS requires all
declarations in scope for a function to match.

You might be able to get away with it, but I don't think it's a good
idea. 

=========
The opinions expressed above are mine.

"The 80x86 world has no excuse for the mess it has gotten itself into."
					-- Doug Gwyn

dillon@CORY.BERKELEY.EDU (Matt Dillon) (04/16/88)

:>	You may accuse me of being lazy, but it works, and I think it makes
:>my code more readable.
:
:I don't think it improves readability.  It seems to me you have the
:choice of doing either:
:	Glorp *GetGlorp();
:	Glorp a_glorp;
:
:	a_glorp = GetGlorp();

	Obviously.  But what happens when you use AllocMem() to allocate
	a structure, then an array of something, then some other
	structure, etc....?  void * gets to be *real* useful and makes
	code a lot easier to understand.

					-Matt

shf@well.UUCP (Stuart H. Ferguson) (04/17/88)

The discussion is about using "void *" on AllocMem() and how much more
readable this is.

I use a couple of macros, to wit:

#define NEW(typ)         (typ*)AllocMem((LONG)sizeof(typ),0L)
#define FREE(p,typ)      FreeMem(p,(LONG)sizeof(typ))

#define NEW_N(typ,n)     (typ*)AllocMem((LONG)((n)*sizeof(typ)),0L)
#define FREE_N(p,typ,n)  FreeMem(p,(LONG)((n)*sizeof(typ)))

So when I want a new "struct Blorch," I just say,

	foo = NEW(struct Blorch);

Reminds my of my Pascal days ... ;-)

This is actually a religious issue, more or less, but I don't really have
anything agaist "void *".  The macros work on any "C," as far as I know, 
however.
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC		(shf@Solar.Stanford.EDU)