void * (was Re: malloc())

guy at sun.UUCP guy at sun.UUCP
Wed May 21 04:36:17 AEST 1986


> So, although not necessarily synonyms, they ("char *" and "void *" - gh)
> do have the same properties, except that "char *" conversions usually
> require a cast to be acceptable.

Well,

	1) they don't have the same properties - if you dereference a
	   "char *", you get a "char", while if you dereference a "void *",
	   you get a "void", which means you can't dereference a "void *"
	   without casting it to a pointer to some meaningful type (this,
	   in answer to your question below, is presumably why "void *"
	   was chosen)

	2) the fact that "char *" conversions require a cast is NOT a
	   characteristic of the language, but a characteristic of the
	   compiler/"lint".  A C compiler which never generated any
	   warnings about pointer conversions would not be in violation
	   of the language specification.

	   As such, a C compiler could, if its author wanted it to,
	   generate warning messages about "illegal pointer combination"
	   and about "possible pointer alignment problem" for implicit
	   conversions (i.e., conversions not involving casts) between
	   "char *" and other pointers, and not generate them for
	   implicit conversions between "void *" and other pointers.
	   It could generate both warning messages for all implicit pointer
	   conversions, and generate them for all explicit pointer
	   conversions except those involving "void *".

	   A compiler which did so would not assign "char *" and "void *"
	   the same properties, since replacing objects of type "void *"
	   with objects of type "char *" in some expressions would cause
	   warnings to be issued.

> What I had in mind was that "ALIGN *" would be a synonym for "int *" or
> whatever happens to be the most restrictive pointer type.  The "guarantee"
> would be as good as the "guarantee" on an "int *".

I.e., not very good.  Again, you would have to trust "malloc" to know what
it was doing, just as you would have to do if it returned "void *".
Somewhere inside the guts of "malloc" there would probably be an conversion
of a "char *" to a "void *" or an "ALIGN *", and you'd have to hope that the
algorithm used by "malloc" guaranteed that the pointer being converted were
aligned properly.

> Well, what *is* the justification for adding "void *" to the language?  To
> allow people to shove pointers around without casts?

No.  One could allow people to shove pointers around with casts simply by
removing some warning messages from some current C compilers.

> To make lint shut up about malloc()?

In a sense, yes.  It also makes it possible to use "opaque pointers" without
getting complaints from the compiler.  We currently run our kernel through
"lint" before it goes out the door; the "lint" rules in the 4.2BSD kernel
"makefile" run the "lint" output through "egrep" to eliminate "possible
pointer alignment problem" messages, since there are a number of cases where
there are no such problems but we have no way to tell "lint" that.  If
"caddr_t" were "void *" instead of "char *", we wouldn't have to strip out
all "possible pointer alignment problem" messages; any that appeared would
indicate that there was a real problem in the code.

> Or just to distinguish "generic pointers" from pointers that can be
> dereferenced?  (Could be done with a typedef.  So could "void", but
> they put it in anyway.)

You can do "void" and "caddr_t" (or whatever you want to call a "generic
pointer") with "typedefs", but you can't make the compiler recognize their
unique properties that way.  If you do "typedef int void;", the compiler
will not recognize that casting something to "void" throws its argument
away, and certainly won't recognize that "void foo();" declares a function
which doesn't return a value.  If you declared "caddr_t foop;", the compiler
would let you dereference "foop" in an expression.

As such, I presume by "distinguish" you mean "distinguish *for the reader of
code*", not "distinguish for the compiler".  That is one thing you can use
"void *" to do, but it's not the only reason it was proposed.

> I do not strongly object to the addition of "void *", but I am worried about
> it "hiding" errors.  (I'm one of those purists who thinks that programmers
> *should* use casts to change types.)

Yes, if some compiler implementer misses the obvious, it could be used to
hide errors.  (Unfortunately, I've seen a lot of cases where implementers
miss the obvious.)  If one assumes that the current PCC/"lint" rules for
complaining about pointer conversions are correct, the correct extension of
those rules to "void *" is:

	implicit conversions to and from "void *" should generate
	"illegal pointer combination" warnings (although they need not
	give "possible pointer alignment problem" warnings)

	explicit conversions (i.e., conversions with casts) should not
	give any "possible pointer alignment problem" warnings; if you
	specify the "-c" flag to older "lint"s, or the "-p" flag to
	newer ones (both of which turn on the "complain about all pointer
	casts" flag - older versions give "illegal pointer combination"
	warnings, and newer ones give "pointer casts may be troublesome"),
	it should probably continue to give warnings.

This means that if you're going to toss pointers around casually, the
compiler is at least going to warn you about it; you have to say "I know
what I'm doing, shut up" by adding casts if you don't want errors.  In fact,
I would suggest that all conversions between pointers other than "void *"
should get "illegal pointer combination" (or, perhaps, "questionable pointer
combination", at least in some cases, since the C standard does permit
certain combinations) warnings, even if casts are used.

> Also, it's a misnomer; it has nothing to do with "void".

I presume the reason why "void *" was chosen is, as stated above, that a
pointer of type "void *" would, when dereferenced, yield an object of type
"void", and as such dereferencing a "void *" would be illegal, just as using
a function of type "void" as if it returned a value would be.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy at sun.arpa



More information about the Comp.lang.c mailing list