[comp.sys.amiga] 'void *'

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

Matt Dillon writes:
>	...  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.

That's when you use a cast.  You can't simply pretend all pointers are
`void *'.  It's just not right.  And what happens when someone tries
to compile your code with a compiler that doesn't handle `void *'?

As for readability, several people have posted macros for NEW and FREE
that allow you to correctly and readably manipulate pointers returned
by AllocMem().

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

"I no longer think of something as a computer unless
 it's connected to a network."
					-- Peter Weinberger

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

:Matt Dillon writes:
:>	...  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.
:
:That's when you use a cast.  You can't simply pretend all pointers are
:`void *'.  It's just not right.  And what happens when someone tries
:to compile your code with a compiler that doesn't handle `void *'?

	Damn It! It's just not right! It makes little sense to declare
	AllocMem() as returning char * when you know it doesn't!  Which
	is worse?  Saying a function returns something it doesn't and
	using casts, or saying a function can return several (pointer)
	types ala void * and not use casts?

	What happens when someone tries to compile my code with a 
	compiler that doesn't handle enumerations?

	What happens when someone tries to compile my code with a
	compiler that doesn't handle structure assignments?

	What happens when someone tries to compile my code with a
	compiler that doesn't handle structure return values?

	What happens when someone tries to compile my code with a
	compiler that doesn't understand what a signed char is?

	...	Get the point? 

				-Matt

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

Matt Dillon writes:
>Dave Sill writes:
>:That's when you use a cast.  You can't simply pretend all pointers are
>:`void *'.  It's just not right.  And what happens when someone tries
>:to compile your code with a compiler that doesn't handle `void *'?
>
>	Damn It! It's just not right! It makes little sense to declare
>	AllocMem() as returning char * when you know it doesn't!

But it does!  Just because you're using the return values as if they
were different types doesn't change the fact that it's declared as one
single type, probably `char *'.

> Which	is worse?  Saying a function returns something it doesn't and
>	using casts, or saying a function can return several (pointer)
>	types ala void * and not use casts?

That's not the right question.  Either way you're declaring a function
to return one type and converting the return value to what you need.
The choice is between using `char *' and casts versus `void *' and no
casts.

The first method, let's call it the K&R method, works on ALL C
compilers: past, present and future.  Absolutely guaranteed.  The
second, or ANSI method, works on only those compilers that claim to
conform to the latest draft.

>	What happens when someone tries to compile my code with a 
>	compiler that doesn't handle enumerations?
>
>	What happens when someone tries to compile my code with a
>	compiler that doesn't handle structure assignments?
>
>	What happens when someone tries to compile my code with a
>	compiler that doesn't handle structure return values?
>
>	What happens when someone tries to compile my code with a
>	compiler that doesn't understand what a signed char is?
>
>	...	Get the point? 

Yeah, I do.  But it's not the same.  There have never been any
guarantees about structure assignment, structure return values, or 
`enum' types.  They, like `void *', were additions to C.

Do you get my point?  All C compilers correctly handle the conversion
of `char *' to pointer to anything; few have `void *'. Why should you
let your laziness get in the way of the portability of your code to
other Amiga C compilers?  Why not type a few extra casts just to be
sure?  How much effort does it really take to do it right? 

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

"In case of doubt, decide in favor of what is correct."
					-- Karl Kraus

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

>Do you get my point?  All C compilers correctly handle the conversion
>of `char *' to pointer to anything; few have `void *'. Why should you
>let your laziness get in the way of the portability of your code to
>other Amiga C compilers? 

	It depends on your definition of 'right'.  If you want to limit
yourself to obsolete versions of C, be my guest.  In my experience, to
write a truely portable C program (e.g. 32 bit int UNIX compiler to, say,
an IBM-PC C compiler) takes twice as long and as half as readable no
matter what you do.

>Why not type a few extra casts just to be
>sure?  How much effort does it really take to do it right? 

	It sounds like you aren't sure of your own code.  I don't make
those kind of mistakes.  The type on the right is obvious since it is
the same as the type on the left (in a pointer assignment); I don't need
to be told twice, and when I read my source 10 years from now it will
look as clear cut and clean and understandable as it did when I first 
wrote it.  KEEP IN MIND that this whole argument deals solely with
the declaration of functions that return different pointer types at
different times.

				-Matt

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

>	It depends on your definition of 'right'.  If you want to limit
>yourself to obsolete versions of C, be my guest.

I guess you're still missing my point.  Using the K&R style doesn't
limit you to any particular compilers at all; using `void *' limits
you to "ANSI" compilers.

>In my experience, to
>write a [truly] portable C program (e.g. 32 bit int UNIX compiler to, say,
>an IBM-PC C compiler) takes twice as long and as half as readable no
>matter what you do.

I totally agree.  However, I'm not suggesting you make your Amiga
programs truly portable.  I'm suggesting you make them easier to port
to other Amiga compilers.

>	It sounds like you aren't sure of your own code.

I wonder what makes you say that.  I'm sure of my code because I stick
to the least common denominator, i.e. K&R C.  Remember, we haven't
even got an ANSI standard for C yet.  How long do you think it will be
before *everyone* has replaced his compiler with a real ANSI-
compatible compiler?

>The type on the right is obvious since it is
>the same as the type on the left (in a pointer assignment); I don't need
>to be told twice, and when I read my source 10 years from now it will
>look as clear cut and clean and understandable as it did when I first 
>wrote it.

Yes, the ANSI solution is cleaner.  But the K&R solution is universal.
I think it's premature to adopt the non-backward-compatible ANSI
solution when there is a universal solution.  I also think it's worth
sacrificing a little code clarity for intercompiler portability.

>KEEP IN MIND that this whole argument deals solely with
>the declaration of functions that return different pointer types at
>different times.

It really started with:
>>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);

(Which I still think is wrong.)  What we're arguing about *is*
functions that return different kinds of pointers.

This is obviously becoming a religious issue.  I think both sides have
made their points, and I probably won't post another message on the
topic.  I'll conclude with a final summary of the two sides, as I see
them.

			Pros			Cons
-----------------------------------------------------------------
K&R `char *'	 	all compilers		messy casts req'd
			including ANSI
-----------------------------------------------------------------
ANSI `void *'		ANSI compilers only	no messy casts
-----------------------------------------------------------------

As an aside, which Amiga C compilers *are* "ANSI"-compatible?  Which
aren't?

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

"There's always a place for least common denominators on the market."
					-- Bill Joy

doug@eris (Doug Merritt) (04/21/88)

In article <8804200436.AA22240@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes:
>	It sounds like you aren't sure of your own code.  I don't make
>those kind of mistakes.

I hope you knocked on wood when you said this. It may be that you
avoid this in general. Let me know if you continue to hit 100%
perfect on the subject now that you claimed it. 1/2 :-)

>to be told twice, and when I read my source 10 years from now it will
>look as clear cut and clean and understandable as it did when I first 
>wrote it.

Well. Maybe. Thin ice. You may be the exception to the general rule,
but I hope you're aware in general that people believe this more often
than it's the actual case. When I look at C programs I wrote 10 years
ago, I'm more often proud of the ideas than the actual implementation.
Maybe you're a lot better than I ever was. That's good. But be cautious,
just in case. There's no gain in convincing yourself that your current
level of expertise will be your maximum in the future; that tends to
limit your own future learning and growth.
	Doug Merritt		doug@mica.berkeley.edu (ucbvax!mica!doug)
			or	ucbvax!unisoft!certes!doug
			or	sun.com!cup.portal.com!doug-merritt