[comp.lang.c] commom malloc/free practice breaks standard - author strikes back

bdm@anucsd.oz (Brendan McKay) (10/16/89)

Here are my responses to the first four "rebuttals" of my posting.
 
(A) Mike Haertel <mike@stolaf.edu>
 
> >* assigning a void* to an OBJ* involves rounding up to an even address
> The standard doesn't say anything about "rounding" pointers.
 
Nor should it---that's an implementation issue.  I'm allowed to implement
pointers and pointer casting in any way I please so long as the behaviour of
my implementation satisfies the requirements of the standard.
 
> Assigning a misaligned void* to an OBJ* might well cause a trap when
> the OBJ* is dereferenced.  Or even when the void* is just assigned to it!
 
What's a "misaligned void*"?  If you mean "a value of void* which cannot be
safely cast to OBJ* and dereferenced", then my implementation of malloc()
does not return any such values.   If you mean "a value of void* corresponding
to an odd underlying address", then no such traps will occur in my
implementation.  Are they compulsory?
 
> >* malloc allocates sufficient space so that it will cover an object of
> >  type OBJ even when the void* value returned is rounded up to even.
> >  (Thus, sometimes it actually allocates one more cell than it is asked for.)
 
> No!  The pointer returned by malloc() always has the most pessimistic
> necessary alignment.
 
I'm not sure what it means for a value of type A* to have alignment suitable
for type B*, unless it means that I can cast that A* to a B* and use it
to access a B. By that criterion, my malloc() returns values suitable for OBJ*.
The standard does have a concept of "type A has more strict
alignment requirement than type B", though.  It means I can confidentally
cast a A* to an B* and use the result, but may have trouble the other way
around.  Note that it refers to the result of casts, not to some arithmetic
property of underlying machine addresses or whatever.
 
=======
(B) Conor P. Cahill   <uunet!virtech!cpcahil>
 
> > "The pointer returned if the allocation succeeds is such that, if it is cast
> > to a pointer to any type of object and then that pointer is cast to type
> > void*, the original value is recovered."
 
> That is the meaning of the "suitably aligned so that it may be
> assigned to a pointer to any type of object and then used to access such an
> object..." (Section 4.10.3).
 
That was probably the intention, but it certainly isn't what it says.
My hypothetical implementation returns a value which can always be assigned
to an OBJ* and used to access an OBJ.  Doesn't it?
 
> An assignment of a void* pointer that is an invalid address for an OBJ*
> will usually cause a core drop at the point of dereference and may cause
> a core drop at the assignment.
 
The standard permits implementations where some pointer casting causes
exceptions or results in values which cannot be deferenced.  It doesn't
make such implementations compulsory.
 
> It *should* not modify the value of the pointer.
 
You have to be careful when you talk about "the value of the pointer"
across different pointer types.  If you mean "underlying bit pattern"
you are wrong: many existing implementations change bit patterns for
some pointer casts (consider char* on a word-addressed machine).
If you mean that the value before the cast must test as equal to that
after the cast, then my implementation *does* have that property.
Check the section on comparisons between pointers of different types---
it requires *casting*.
 
=====
(C) Scott A. Rotondo  <scott@Altos.COM>
 
> > Consider the following hypothetical implementation:
> > * pointers are implemented as memory addresses in the common way
> > * objects of type OBJ require even addresses.
> > * assigning a void* to an OBJ* involves rounding up to an even address
> > * malloc allocates sufficient space so that it will cover an object of
> >   type OBJ even when the void* value returned is rounded up to even.
> >   (Thus, sometimes it actually allocates one more cell than it is asked for.)
> > * assigning an OBJ* to a void* involves no change of address
 
> Your hypothetical implementation is not Standard-conforming because of
> the fourth point above.  Your quote from section 4.10.3 requires that
> the pointer returned from malloc() be aligned according to the most
> restrictive alignment requirements for this implementation.  That means
> that the cast from void * to OBJ * must leave the address unchanged
 
I have trouble with both "most restrictive alignment" (only used by the
standard as a property of types, not of pointer values) and "address
unchanged" (see part (B) above).
 
> (the internal pointer representation may change, but that is
> invisible).  Similarly, the cast from OBJ * to void * will not change
> the address.
 
That much is (sort of) implied by the rule that the pair of casts
OBJ* -> void* -> OBJ* gets you back where you started.  It's the other
cast which causes the trouble.
 
> > This implementation is unusual, but seems to obey the rules.  There was no
> > requirement that malloc() return an even address, only that the value
> > returned could be used after casting to OBJ*.  However, when objptr is cast
> > back to void* for passing to free(), the value obtained is possibly different
> > from the one returned by malloc(), thus breaking the rules for free().
>
> As indicated above, malloc() must return an even address in this
> implementation.  Since neither cast will change the address, free()
> will work as expected.
 
Already answered, I think.
 
> > No doubt this problem was unintentional.  It could easily be fixed by a
> > sentence reading something like "The pointer returned if the allocation
> > succeeds is such that, if it is cast to a pointer to any type of object
> > and then that pointer is cast to type void*, the original value is
> > recovered."
 
> This is precisely the meaning of the section 4.10.3 alignment rule.
 
The intention, I'm sure.  The meaning is another matter.
 
=====
(D) Doug Gwyn  <gwyn@smoke.brl.mil>
> >Note that I'm not claiming the Standard is broken, only that the writers of
> >the standard have accidentally ruled out a common coding practice.
 
> No, we didn't -- any valid pointer can be converted to a pointer that
> has less strict alignment and back, so that the result compares equal
> to the original pointer,
 
I can only find this rule for OBJ* -> void* -> OBJ* and OBJ* -> char* -> OBJ*.
Am I missing a section?
 
> void* has the same alignment requirement as
> char*, and converting a coarsely-aligned malloc() void* to OBJ* does
> NOT result in adjustment of the alignment.
 
Hang on.  OBJ* has a MORE strict alignment requirement than void*, not less,
so the general rule you mention doesn't apply.  Moreover, I can't find any
support in the standard for your concept "coarsely-aligned malloc()" except
as it applies to the validity and result of a pointer cast.  By that
criterion, my hypothetical implementation is fine (until proven otherwise).
 
> Apply ALL the relevant constraints and you'll find that there is no problem
> with typical malloc()/free() usage.
 
Maybe, but I need more convincing yet.
 
===========================================================================
 
Oh, I'm only a poor theoretician having a bit of fun.  Keep it coming.
Is anyone out there brave enough to AGREE with me?
 
Brendan McKay.   bdm@anucsd.oz  or  bdm@anucsd.oz.au
 

cpcahil@virtech.UUCP (Conor P. Cahill) (10/17/89)

In article <1989Oct16.111059.3840@anucsd.oz>, bdm@anucsd.oz (Brendan McKay) writes:
> > That is the meaning of the "suitably aligned so that it may be
> > assigned to a pointer to any type of object and then used to access such an
> > object..." (Section 4.10.3).
>  
> That was probably the intention, but it certainly isn't what it says.
> My hypothetical implementation returns a value which can always be assigned
> to an OBJ* and used to access an OBJ.  Doesn't it?

Lets start again.  For any implementation there may exist alignment 
requirements that differ depending upon the type of data being dereferenced.
An example implementation will be where OBJ * must be aligned on a word
boundary, but void * can be on a byte boundary.

In this implementation malloc() MUST always return a pointer to the worst
case.  Another way of putting it is in the example above malloc must return
a OBJ * that is cast to a void *.  

So
		malloc gets a OBJ *, returns (void *) OBJ *
		which you then cast to an OBJ * which when you 
		call free you cast to a VOID * 

in a simpler wording

		OBJ * -> void * -> OBJ * -> void *

which IS REQUIRED by the standard.

> > An assignment of a void* pointer that is an invalid address for an OBJ*
> > will usually cause a core drop at the point of dereference and may cause
> > a core drop at the assignment.
>  
> The standard permits implementations where some pointer casting causes
> exceptions or results in values which cannot be deferenced.  It doesn't
> make such implementations compulsory.

And I didn't say it was compulsory.  That is the purpose of the *usually* that
I placed in the sentence.

> Is anyone out there brave enough to AGREE with me?

Brave has nothing to do with it.  You just don't understand the concept of
malloc() returning a suitably alligned pointer.


-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

chris@mimsy.umd.edu (Chris Torek) (10/17/89)

>> Is anyone out there brave enough to AGREE with me?

In article <1284@virtech.UUCP> cpcahil@virtech.UUCP (Conor P. Cahill) writes:
>Brave has nothing to do with it.  You just don't understand the concept of
>malloc() returning a suitably alligned pointer.

I am sure the fellow *does* understand the concept.  He is not saying
that this is (or is not) how things work.  He is simply saying that, in
his reading, the proposed standard does not make sufficient constraints
on the implementation to force the implementation to work.  In his
opinion, it would be possible for an implementation to conform to the
letter of the standard, yet have code like

	p = (struct foo *)malloc(sizeof(struct foo));
	if (p == NULL) ... handle error ...
	... use *p ...
	free((void *)p);

break.
-- 
`They were supposed to be green.'
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

gwyn@smoke.BRL.MIL (Doug Gwyn) (10/17/89)

In article <20203@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>In his opinion, it would be possible for an implementation to conform to
>the letter of the standard, yet have code like ... break.

Yeah, well, I've already explained why he's wrong, and I think the
other respondents have been trying to say pretty much the same thing.

I don't think we need to spend any more time on this.  If there were
a real problem with the standard, that would be one thing, but since
that has not been demonstrated and arguments to the contrary have not
been refuted (restatement of the original claim does not constitute
refutation), I for one consider the matter settled.

rhg@cpsolv.UUCP (Richard H. Gumpertz) (10/17/89)

1) It seems to me that the UNUSUAL implementation of malloc is OK by the
current standard.

2) The standard is NOT meant to protect the compiler implementor from himself.
It is still the implementors duty to make sure things work properly.

3) True, the standard currently seems to put the burden on the end-user to save
the uncast (void *) value returned from malloc as well as the cast value, with
only the former used for free and realloc.  I have yet to see any program that
does so.

4) If the implementor of malloc wants to return odd pointers, knowing that
type-casting will round up (also UNUSUAL but legal), then he really should
implement free so that it will work even on all possible rounded-up values!
No sane compiler (actually, library) implementor should implement things that
don't work with common coding style.

5) The appropriate changes to the standard would be in the sections on free
and realloc.  In particular, 4.10.3.2 should be expanded to indicate not just
"a pointer earlier returned by the calloc, malloc, or realloc" but rather a
pointer that may have been cast using "(void *) (any-type *)" from the value
returned by calloc, malloc, or realloc.  Similar changes to 4.10.3.4.   Note
that this change is really NEEDED in the standard anyway to allow the end-user
to use the doubly-cast value for free rather than the original value.

6) By the way, it appears that if "void *" were bigger than other pointers, an
implementation would currently be free to hide any information (such as size,
buddy-pointers, etc.) that it wants in the value of malloc and expect to get it
back in the free call. The above fixes to the standard would prohibit this as
well (unless the object pointers also carried the extra "hidden" information).

7) By fixing the definitions of free and realloc, rather than restraining
pointer casting, we have left the maximal flexibility for the compiler and
library implementor.

8) By the way, pointer comparison between "OBJECT *" and "void *" requires that
the pointer to the object be (implicitly) converted to "void *".  Hence,
	void *x; mumble *y;
	y = (mumble *) (x = malloc(...));
	x == y
will probably yield false in this rounding implementation: a similar surprise
to the poor programmer (but legal).  Contrary to what someone stated earlier
in this thread, explicit type-casting is NOT required by the standard for
pointer comparison with "void *".  See the last paragraph of 3.3.9.  Hence,
I again recommend against the unusual rounding implementation.
-- 
==========================================================================
| Richard H. Gumpertz    rhg@cpsolv.UUCP -or- ...uunet!amgraf!cpsolv!rhg |
| Computer Problem Solving, 8905 Mohawk Lane, Leawood, Kansas 66206-1749 |
==========================================================================

dhesi@sun505.UUCP (Rahul Dhesi) (10/18/89)

>> ...any valid pointer can be converted to a pointer that
>> has less strict alignment and back, so that the result compares equal
>> to the original pointer,
> 
>I can only find this rule for OBJ* -> void* -> OBJ* and OBJ* -> char* -> OBJ*.
>Am I missing a section?

This may the key point.

I, like many others, rely on the gurus in comp.lang.c for much valuable
information.  Can somebody quote chapter and verse to show that the
standard does require the series of casts

     void * ->  OBJ *  ->  void *

to yield the original pointer?

Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi
Do not use From: address for reply if it contains "sun".

scott@altos86.Altos.COM (Scott A. Rotondo) (10/19/89)

Brendan: I have trouble with both "most restrictive alignment" (only
	 used by the standard as a property of types, not of pointer
	 values) and "address unchanged" (see part (B) above).

Types have alignment restrictions.  The same restrictions apply to the
addresses represented by pointers to objects which have types.
Malloc() must return pointers whose addresses meet the most restrictive
of these alignment requirements.

Brendan: No doubt this problem was unintentional.  It could easily be
	 fixed by a sentence reading something like "The pointer
	 returned if the allocation succeeds is such that, if it is
	 cast to a pointer to any type of object and then that pointer
	 is cast to type void*, the original value is recovered."
Scott:   This is precisely the meaning of the section 4.10.3 alignment
	 rule.
Brendan: The intention, I'm sure.  The meaning is another matter.

Section 4.10.3 doesn't simply state that you must be able to cast or assign
the pointer and use it; it says that you must be able to use the pointer
because it is "suitably aligned."  Your hypothetical implementation only
meets the weaker of these two conditions.
-- 
===============================================================================
Scott A. Rotondo, Altos Computer Systems			 (408) 946-6700

{sun|pyramid|uunet}!altos86!scott				scott@Altos.COM	

gwyn@smoke.BRL.MIL (Doug Gwyn) (10/19/89)

In article <416@cpsolv.UUCP> rhg@cpsolv.uucp (Richard H. Gumpertz) writes:
>4) If the implementor of malloc wants to return odd pointers, knowing that
>type-casting will round up (also UNUSUAL but legal), ...

NO, it is NOT legal!  Sheesh.

>No sane compiler (actually, library) implementor should implement things that
>don't work with common coding style.

This is a useless criterion.  Some common coding style is ERRONEOUS.
A C implementor should implement the language specified in the Standard,
providing whatever additional value seems appropriate.  A programmer
should avoid asking of an implementation things that are not guaranteed
by the language standard.  That is the "treaty point" that makes the
Standard useful.

>5) The appropriate changes to the standard would be in the sections on free
>and realloc.  In particular, 4.10.3.2 should be expanded to indicate not just
>"a pointer earlier returned by the calloc, malloc, or realloc" but rather a
>pointer that may have been cast using "(void *) (any-type *)" from the value
>returned by calloc, malloc, or realloc.  Similar changes to 4.10.3.4.   Note
>that this change is really NEEDED in the standard anyway to allow the end-user
>to use the doubly-cast value for free rather than the original value.

Wrong, wrong, wrong.  The Standard already says what was intended in
this regard.  It did NOT intend for your interpretation to be applied.
In fact, what you're asking for can be deduced as a special case from
the existing specifications in the Standard; no additional wording is
necessary to enforce this constraint.

>Hence, I again recommend against the unusual rounding implementation.

I recommend against it because it is not standard conforming.

rhg@cpsolv.UUCP (Richard H. Gumpertz) (10/20/89)

In article <11334@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>NO, it is NOT legal!  Sheesh.

OK, where in the standard does it say it is illegal?

>Wrong, wrong, wrong.  The Standard already says what was intended in
>this regard.  It did NOT intend for your interpretation to be applied.
>In fact, what you're asking for can be deduced as a special case from
>the existing specifications in the Standard; no additional wording is
>necessary to enforce this constraint.

Again, where in the standard does it say that?

Arguments that just make assertions without citation don't hold much water.
I cannot find anything that says conversion from "void *" to "obj *" cannot
round up.  In fact,I cannot find anything in the standard that says
      free((void *) (object *) malloc(sizeof(object)))
will work: the standard only says that
      free(malloc(sizeof(object)))
will work.  Please tell me what section I have overlooked or stop saying
the standard already has things that I cannot find.
-- 
==========================================================================
| Richard H. Gumpertz    rhg@cpsolv.UUCP -or- ...uunet!amgraf!cpsolv!rhg |
| Computer Problem Solving, 8905 Mohawk Lane, Leawood, Kansas 66206-1749 |
==========================================================================

datanguay@watmath.waterloo.edu (David Adrien Tanguay) (10/20/89)

In article <992@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
>I, like many others, rely on the gurus in comp.lang.c for much valuable
>information.  Can somebody quote chapter and verse to show that the
>standard does require the series of casts
>
>     void * ->  OBJ *  ->  void *
>
>to yield the original pointer?

For a general pointer this is not the case, but the argument is about
pointers returned by malloc. From section 4.10.3 "Memory management functions":

	The pointer returned if the allocation succeeds is suitably aligned
	so that it may be assigned to a pointer to any type of object and
	then used to access such an object or an array of such objects in
	the space allocated (until the space is explicitly freed or
	reallocated). Each such allocation shall yield a pointer to an
	object disjoint from any other object. The pointer returned points
	to the start (lowest byte address) of the allocated space.

I don't see anything there (or anywhere in 4.10.3.*) that asserts the above
series of casts.

David Tanguay

cpcahil@virtech.UUCP (Conor P. Cahill) (10/21/89)

In article <992@cirrusl.UUCP>, dhesi@sun505.UUCP (Rahul Dhesi) writes:
> information.  Can somebody quote chapter and verse to show that the
> standard does require the series of casts
> 
>      void * ->  OBJ *  ->  void *
> 
> to yield the original pointer?

The standard doesn't require this.  It requires that 

      OBJ * -> void * ->  OBJ * 

yield the original pointer.

-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

amull@Morgan.COM (Andrew P. Mullhaupt) (10/21/89)

In article <992@cirrusl.UUCP>, dhesi@sun505.UUCP (Rahul Dhesi) writes:
> 
> I, like many others, rely on the gurus in comp.lang.c for much valuable
> information.  Can somebody quote chapter and verse to show that the
> standard does require the series of casts
> 
>      void * ->  OBJ *  ->  void *
> 
> to yield the original pointer?
> 

The short answer seems to be that the standard does not always require
this; and the long answer follows:

(If you don't want to read the long answer; now's the time ...)


Well, in one commonly available source, "C: A Reference Manual" by S. P. 
Hardison and G. L. Steele, Jr., (1987, 1984) we find:

page 115.: "Draft Proposed ANSI C introduces the type 'void *', or pointer
to void, to represent a 'universal' data pointer."

and then 

page 268.: "All other pointer types (except perhaps function pointers) can
be converted to type void * and back without change;"

Which answers the closely related question; that the cast sequence

	OBJ * -> void * -> OBJ *

must not change the pointer to OBJ. In particular, if the pointer to type
void in question is the result of a cast  OBJ * -> void *  then the 
subsequent cast sequence

	void * -> OBJ * -> void *

cannot change the value of the pointer to type void; via the apparent theorem:

	{OBJ * -> void * -> OBJ *} -> void * == {OBJ *} -> void *

where == indicates that the two cast sequences arrive at the same pointer to
void by replacement of the equivalent cast sequences in braces. (The braces 
are not indicative of C syntax, along with the -> symbol for typecasting.)


Now on page 126.: "In general, if the alignment requirement for a type S is at
least as stringent for a type D, (...) then converting a 'pointer to type S'
to a 'pointer to type D' is safe. 'Safe' here means that the resulting pointer
to type D will work as expected if used to fetch or store an object of type D,
and that a subsequent conversion back to the original pointer type will recover
the original pointer. A corollary to this is that any data pointer can be 
converted to type  char *  and back safely."

It seems that the intent of the proposed standard is that the alignment 
requirement for type void is no more stringent than that of any other type.
(This would seem to make sense, since you shouldn't have to align something
you do not ever actually intend to store - an object of type void.)

Further on page 126.: "If the alignment requirement for a type S is less
stringent than that for type D, then the conversion from a 'pointer to type S'
to a 'pointer to type D' could result in either of two kinds of unexpected
behavior. First, an attempt to use the resulting pointer to fetch or store
an object of type D may cause an error, halting the program. Second, the
hardware or implementation may 'adjust' the destination pointer to be legal,
usually by forcing it back to the nearest previous legal address. A subsequent
conversion back to the original pointer type may not recover the original
pointer."

It is entirely clear if you accept that void is no more stringent than any
other type, then types not of this minimal stringency are not guaranteed to
survive the cast sequence in question unless a precondition essentially that
the pointer to void is a legitimate pointer to OBJ before the casting begins.

One should expect that if such a precondition is false, that the desired cast
sequence is not only unguaranteed by the Proposed Draft ANSI Standard, but
likely to be unpleasant at run-time; i.e. a bug.

One often has occasion to cast a pointer to void which is the result of one 
of the alloc family of functions. These return pointers which are guaranteed
to satisfy even the most stringent alignment requirements, (Harbison & Steele
page 345.) One can think of this as being the same as if the pointer to the
desired type was assigned by the allocation function, and then cast to  void *
where by the above theorem it can be safely cast to and from  void *.

I can't find the answer to an even more obscure question arising from this
line of inquiry: It seems that the sometime guarantee of the theorem above
is false in the case that the type  OBJ *  is defined in a typedef with the
volatile type specifier. (I.e. I can't seem to eliminate the scary possibility
of a volatile pointer!) The "obvious" trick is illegal; consider:

typedef OBJ *ptr;		/* ptr is type 'pointer to OBJ' */
typedef volatile ptr BLUNGE;	/* BLUNGE is the volatile kind */

This is explicitly forbidden by Draft Proposed ANSI C, "Typedef names should
not be mixed with other type specifiers" (Harbison & Steele page 116.) I 
haven't had enough experience chasing the lexical rules and syntax to ensure
that no other way to declare a volatile pointer type exists; but I hope it's
impossible. Ominously, we have been able to get  gcc  to accept the declaration

char * volatile p;

but I don't know what it really is or means.

Later,
Andrew Mullhaupt

gwyn@smoke.BRL.MIL (Doug Gwyn) (10/22/89)

In article <420@cpsolv.UUCP> rhg@cpsolv.uucp (Richard H. Gumpertz) writes:
>Please tell me what section I have overlooked or stop saying
>the standard already has things that I cannot find.

If you've been following this thread, you should have already seen
the answers to your questions.

I *know* the Standard has things you cannot find.

scott@altos86.Altos.COM (Scott A. Rotondo) (10/24/89)

In article <420@cpsolv.UUCP> rhg@cpsolv.uucp (Richard H. Gumpertz) writes:
> Arguments that just make assertions without citation don't hold much water.
> I cannot find anything that says conversion from "void *" to "obj *" cannot
> round up.  In fact,I cannot find anything in the standard that says
>       free((void *) (object *) malloc(sizeof(object)))
> will work: the standard only says that
>       free(malloc(sizeof(object)))
> will work.  Please tell me what section I have overlooked or stop saying
> the standard already has things that I cannot find.

1. No one (to my knowledge) has claimed that conversion from "void *"
to "obj *" is allowed to change the pointer's address if the "void *"
is already aligned according to the requirements for "obj *".

2. Section 4.10.3 guarantees that the "void *" returned by malloc() is
already aligned according to the requirements for "obj *", no matter
what type "obj" represents.  Therefore, no conversion from "void *" to
"obj *" and back to "void *" can possibly change the pointer's
address.

Please note that the phrase "change the pointer's address" includes
"rounding up" the address, but it does not include changing the format
of the pointer without changing the address to which it points.  The
format of the pointer is irrelevant because it is visible only to the
implementation.

Anyone who wishes to continue this discussion will have to make the
claim mentioned in paragraph 1 above, that a cast can modify a pointer
address even if it is already aligned.  I caution anyone who considers
making this claim to read the Standard first.
-- 
===============================================================================
Scott A. Rotondo, Altos Computer Systems			 (408) 946-6700

{sun|pyramid|uunet}!altos86!scott				scott@Altos.COM	

bill@twwells.com (T. William Wells) (10/24/89)

In article <420@cpsolv.UUCP> rhg@cpsolv.uucp (Richard H. Gumpertz) writes:
: [nonsense, because he either has an older standard or has't read it very
: carefully.]

I decided to collect the sections of the standard relevant to the
debate. Here they are:

3.1.2.5:

"A pointer to void shall have the same representation and
alignment requirements as a pointer to a character type."

3.2.2.3:

"A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object
type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer."

3.3.4:

"A pointer to an object or incomplete type may be converted to a
pointer to a different object type or a different incomplete type.
The resulting pointer might not be valid if it is improperly
aligned for the type pointed to. It is guaranteed, however, that
a pointer to an object of a given alignment may be converted to a
pointer to an object of the same alignment or a less restrictive
alignment and back again; the result shall compare equal to the
original pointer. (An object that has character type has the
least strict alignment.)"

3.3.9:

"If two pointers to object or incomplete types compare equal,
they point to the same object. If two pointers to functions
compare equal, they point to the same function. If two pointers
point to the same object or function, they compar equal."

4.10.3:

"The pointer returned if the allocation succeeds is suitably
aligned so that it may be assigned to a pointer of any type of
object and then used to access such an object in the space
allocated (until the space is explicitly freed or reallocated).
Each such allocation shall yield a pointer to an object disjoint
from any other object. The pointer returned points to the start
(lowest byte address) of the allocated space."

---
Bill                    { uunet | novavax | ankh | sunvice } !twwells!bill
bill@twwells.com