I'm referring here to the addresses that show up in pointers and
get compared with < and > operators. Those tests (probably on
virtual addresses) need to work correctly. If the compiler actually
goes to the trouble of translating virtual to physical addresses
and comparing those, fine, but that puts a lot of restriction on
remapping.
If addresses are translated from what you refer to as 'virtual', the
comparison needs to be done for _untranslated_ versions, and in
practice, i think they are.
For example, the comparison of two pointers to the same object (done
by the compiler with physical addresses) is not allowed to change
during the run of the program. That means no reordering in physical
memory the pages containing parts of a single object. This is a
major pain for a virtual memory implementation. If the program
takes the address of something and hangs on to it, the virtual
memory system may not be allowed to load it anywhere in physical
memory besides where it was first loaded as long as the variable
containing that address (and any variables it was copied to) is
live.
Yes. But only if you compare _physical_ addresses, which, in practice,
you would not do, since the only requirement is that the pointers as
seen from 'C', that is the _virtual_ ones, behave nicely. What happens
at the physical level is unimportant from a 'C' point of view.
For instance, if you are running your software on a x86, the addresses
as seen/generated by your compiler are 'logical adresses' (Intel
terminology), which get translated by the CPU to physical addresses
behind the scenes, but this is completely transparent to the 'C'
program and does not need to be taken into account.
No. Signed or Unsigned: *PICK ONE*, you can't have both. You
also can't have neither.
Hmmm... Not so long ago, you argued
<quote>
Virtual memory addresses may be represented with more complex
structure (e.g. permission bits, ring numbers, etc.) in which case
it's hard to tell what 'signed' or 'unsigned' even means as applied
to the address.
</quote>
Which i think was a pretty good point. Whence the change?
You can, however, set things up so it's impossible to rule out
either one. I'll claim that this is the case with most 32-bit
systems, and systems that have 50% or less of their maximum
memory actually installed.
In those cases it makes no difference, agreed. I don't comment on
wether of not your claim is true.
If it's signed, you shouldn't be able to allocate an object that
straddles 0x7fff.../0x8000... . Incidentally, a good representation
for NULL with signed addresses is the bit pattern 0x8000... but it
still has to compare equal to the integer constant 0.
<quote>
(However, I'll note that having NULL represented as all-bits-zero
makes a pretty good case for an unsigned PC (there are *LOTS* of
these machines), and having NULL represented the same as INT_MIN
or LONG_MIN makes a pretty good case for a signed PC (I know of
none of these). It doesn't really make sense for NULL to punch a
hole in the "middle" of the memory space, with "middle" determined
by the signedness of the PC).
</quote>
The above just seemed to fit here quite well.
The operation of < and > on pointers needs to work correctly.
struct a {
int firstmember;
int secondmember;
}foo;
&foo.firstmember < &foo.secondmember had darn well better
be true, and it had better not change during the run of the program,
even if the struct gets split across pages, regardless of whether
the compiler is comparing virtual or physical addresses.
That's not _that_ hard to arrange, but again, it _only_ needs to be
valid for _logical_ addresses (Intel jargon, i think it corresponds,
loosely, to your 'virtual addresses', but i'm not quite sure), not
_physical_ ones.
It's hard to imagine a "truly signed program counter" with segment
numbers in it. Are the segment numbers what is signed? Signed program
counter doesn't have to imply (nor forbid) that the *offset* is signed.
Ummm... Not quite sure what you mean with "a PC with segment numbers
in it" but i was referring to signed offsets.
Using physical addresses (signed or unsigned) for comparison can
really kill your virtual memory performance.
Using physical addresses (signed or unsigned) for comparison is
stoopid and no CPU and/or Compiler manufacturer would dream of doing
that.
No, my argument is that on many machines, you simply CANNOT TELL
whether the addresses are signed or not (and therefore caring or
worrying about it is not worthwhile), because you cannot get (virtual)
pointers to feed to the < or > operators of appropriate values to
even do the test.
And it's a good point, too.
Often the reasons are things like "you don't
have that much memory (or swap space) installed", or "half the
address space is reserved for the kernel".
Incidentally, I think my first run-in with unsigned pointers involved
the loop:
struct reallybig table[MAX];
struct reallybig *p;
for (p = &table[MAX]; p >= &table[0]; p--) {
... do something with p ...;
}
and &table (data segment started at 0) turned out to be less than
sizeof(table). Gee, why does this loop never terminate?