I must have missed the bit in the C Rationale where the committee
wrote, "We did this for the AS/400". They probably thought it was
obvious, since no other architecture could ever have the same
requirements and support C.
OK, define the behavior of all non-dereferencing accesses on
invalid pointers. Be sure to account for systems with non-linear
address spaces, since nothing else in the C standard excludes them.
Yup. The AS/400 has a set of opcodes for manipulating integers, and
a different set for manipulating pointers. Nothing in C currently
requires it to treat the latter like the former, and I don't see any
reason why it should. (Indeed, I admit to being mystified by Andrew
Reilly's position; what would be gained by requiring that C implemen-
tations have defined behavior for invalid pointers? How is leaving
invalid pointer access undefined by the standard "constraining" C?)
Surely there's some way to catch and ignore the trap from loading an
invalid pointer, though.
No, there is not. The "trap" (a machine check, actually) can be
caught, and it can be responded to, by application code; but ignoring
it is not one of the options. On the AS/400, only LIC (Licensed
Internal Code) can bypass memory protection, and the C implementation
is not LIC.
The AS/400 uses a Single-Level Store. It has *one* large virtual
address space for all user-mode objects in the system: all jobs (the
equivalent of processes), all files, all resources of whatever sort.
It enforces access restrictions not by giving each process its own
virtual address space, but by dynamically granting jobs access to
"materialized" subspaces. (This doesn't apply to processes running
under PACE, AIUI, but that's a special case.)
I mean, it stops _somewhere_ even as it is now,
Yes, it stops: if the machine check isn't handled by the application,
the job is paused and a message is sent to the appropriate message
queue, where a user or operator can respond to it.
That happens under LIC control. The C implementation can't override
it; if it could, it'd be violating the system's security model.
Of course, the C implementation could emulate some other machine with
less-vigilant pointer handling by generating some intermediate
representation and interpreting it at runtime. That would have made
the early AS/400s unusably slow, rather than just annoyingly slow,
for C programs.
But in any case a favorite maxim of comp.lang.c applies here: what
the AS/400, or any other extant implementation, does *does not
matter* to the C standard. If we decommissioned all AS/400s today,
there might be a new architecture tomorrow with some other good
reason for disallowing operations on invalid pointers in C.
--
Michael Wojcik (e-mail address removed)
The lecturer was detailing a proof on the blackboard. He started to say,
"From the above it is obvious that ...". Then he stepped back and thought
deeply for a while. Then he left the room. We waited. Five minutes
later he returned smiling and said, "Yes, it is obvious", and continued
to outline the proof. -- John O'Gorman