effect of free()

Richard O'Keefe ok at cs.mu.oz.au
Sat Sep 9 20:04:00 AEST 1989


In article <2054 at munnari.oz.au> ok at cs.mu.oz.au I wrote
>  Presumably, whatever bit pattern represents the NULL
>pointer on such machines may _also_ cause a trap if loaded into an
>address register

In article <29011 at news.Think.COM>, barmar at think.COM (Barry Margolin) writes:
> Why would an implementation want to do pointer comparisons and
> assignments using address registers?  In some architectures, pointers
> contain additional fields besides just the address, and the address
> register data paths automatically take the address apart properly.
> For instance, Multics pointers have a ring number field and several
> bits called "fault tags", as well as some unused bits.  When comparing
> address registers, the extra fields are automatically ignored.  There
> are also two formats of pointers (one-word "packed" pointers that omit
> the above fields, and two-word full pointers), with different
> instructions for loading and storing each.  If the comparisons were
> done using arithmetic registers lots of shifting and masking would be
> necessary.

The PR1ME 50-series machines are surprisingly similar.  (I wonder if some
ex-MULTICS people had something to do with that design?)  A pointer has
    -  1 "validity" bit
    -  1 "length" bit (0 -> 32 bit, 1 -> 48 bit)
    -  2 "ring" bits (0, 1, and 3=user, as I recall)
    - 12 "segment" bits (four quarter-spaces; 1 OS, 1 shared libraries,
	 1 user stuff, 1 CLI & per-process OS info)
    - 16 "word offset within segment" bits
and if the length bit was 1, there is another 16-bit word with
    -  1 "byte within word" bit.
The extension word nominally had 4 "bit within word" bits, but there
were no instructions for bit addressing on the PR1ME 400 I used.

    Barry Margolin raised a point I hadn't thought of:  there is a
distinction between "these pointers point to the same place", and
"these are the *same* pointer".  A 32-bit pointer and a 48-bit pointer
with 0 extension word on the P400 would be different pointers, but they
could point to the same place.

    This leads me to wonder:  if a compiler sees a statement like
	if (x == y) { .... use x .... }
then when x and y belong to the same *numeric* type and neither x nor y
is changed, it is entitled to translate the statement _as if_ it had been
	if (x == y) { .... use y .... }
This can be handy if y is in a register and x isn't.  Since the conceptual
model for a C pointer is (the identity of an array, an index within the
array), I assume that x == y in C means "x and y point to the same place".

1.  Does the current draft actually say this?

If that is so, then a C compiler which exploits x == y to use y where x
was written is _not_ guaranteed to preserve things like a ring number,
which could be Bad News for people trying to write operating system
kernels in C.  In user-level code on a PR1ME 50 series machine it makes
no difference because the ring is always weakened to an "effective" 3
in user mode anyway, but even in user mode it might make a considerable
difference if the validity bit were ignored in pointer comparison, yet
the "equal if point to same place" semantics would seem to permit that.

2.  According to the current draft, are C compilers allowed to use
    y instead of x if x == y and it is known that x and y cannot have
    changed since that was established?

If, in order to avoid the problem of misteriously losing access rights,
getting pointers with the invalid bit on, and so on, compiler writers
adopt the "same pointer" semantics rather than the "same place" semantics,
the argument for doing pointer comparison in address registers goes away.

Perhaps the answer is that compiler writers for such machines ought to
have a local _SamePtr(x,y) test, and should do optimisation relative
to that rather than relative to x==y.  _SamePtr() should not be in the
standard, of course, but it's worth having a clear comment about this
somewhere in the Rationale.



More information about the Comp.lang.c mailing list