Any word addressed machine where 10 is not correctly aligned for an int
and the pointer to int mapping produces a byte offset from address 0. I
believe the Cray falls into that camp.
<snip>
It's also fairly easy to run into problems with 64 bit CPUs running 32
bit ABIs.
The 16 core MIPS64 NPU sitting here on my desk is one such example.
Any 32 bit code using the KSEG/SSEG kernel segments must take care to
construct sign-extended pointer values. As an example, take the KSEG0
base address. If you end up with:
0x00000000 80000000 (incorrect)
in a 64 bit register rather than:
0xFFFFFFFF 80000000 (correct)
.... you'll crash upon a dereference. Depending on your toolchain and
your configuration of it, a statement such as:
int *p = (int *) 0x80000000;
.... can generate either one! Perhaps even worse, the resulting code
may or may not work depending on the processor's current mode and
whether or not the SR(UX) bit is set in the CPU's status register.
Generally speaking, the newer and nicer toolchain setups will sign
extend for you (because it's what you probably want), and this is fine
because that's what everyone is talking about when they say
"implementation defined". The vanishingly few people that actually
want 0x00000000 80000000 can simply use a uint64_t / unsigned long
long / (u)intptr_t type before converting it to a pointer.
Something to look out for is crossing the sign extension boundary with
arithmetic. This is virtually certain to not be handled properly. If
you think about it, the reason why makes perfect sense: the region
that 32-bit code sees as continuous is in fact composed of the very
discontinuous bottom (0x0000000000000000-0x000000007fffffff) and top
(0xffffffff80000000-0xffffffffffffffff) of the 64 bit space.
For normal 32-bit legacy userspace programs, 0x80000000 and above is
off limits and accesses to it "can't happen", so nobody really cares
except kernel / system software engineers, who are expected to be
aware of the situation.
I've seen an instance in the field of a bug where two pointers printf
() to the same value (in a 32 bit environment) but do not compare
equal with == due to defects in the way that one of them was
constructed. I almost lost my voice from having to tell them "STFU,
it's __not__ a compiler bug".
Mark F. Haigh
(e-mail address removed)