Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.csd.uwm.edu!bionet!ames!uhccux!munnari.oz.au!cs.mu.oz.au!ok From: ok@cs.mu.oz.au (Richard O'Keefe) Newsgroups: comp.lang.c Subject: Re: effect of free() Summary: also PR1ME 50 series Message-ID: <2064@munnari.oz.au> Date: 9 Sep 89 10:04:00 GMT References: <319@cubmol.BIO.COLUMBIA.EDU> <3756@buengc.BU.EDU> <29011@news.Think.COM> Sender: news@cs.mu.oz.au Lines: 72 In article <2054@munnari.oz.au> ok@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@news.Think.COM>, barmar@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.