On Fri, 2 Dec 2022 at 16:48, Thiago Macieira via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
On Friday, 2 December 2022 01:31:31 PST Marcin Jaczewski via Std-Discussion
wrote:
> > Yes. If it helps, the difference has existed since standardization: the
> > comparison is undefined in C89 and unspecified in C++98, so it might be
> > tricky to discover the rationale.
> >
> > Perhaps you could ask SG22 whether they know the cause of the divergence,
> > and whether they're interested in resolving it.
> This could be required by segmented memory and Far Pointer in 16-bit
> architectures.

That only explains why they aren't defined. It doesn't explain why one is
unspecified and the other UB.

We can reason on the consequence: the C standard allows the implementation to
crash if you try to order two pointers from different arrays. If that freedom
had to be reserved, it might be because some old architecture required some
calculation that would result in a fault or trap if the two pointers weren't
from the same array.

I can't think of any such architecture. The closest I can come to is the 16-
bit protected mode of the 80286, with __huge pointers: if the compiler
generated a segment descriptor that wasn't valid then proceeded to load that
into a segment register, it would crash. I don't know if this has ever
existed, though: __huge pointers existed in 16-bit real mode and were gone in
32-bit protected mode, and it's a generation of programming I completely
skipped. The more likely scenario is an overflow trap in the calculations, as
opposed to a memory layout constraint.

Either way, C++ said that while the compiler isn't required to produce a
reliable result, it can't crash or go off the rails either. It must produce a
comparison result and the code continues from there.

 That said, asan does have -fsanitize=pointer-compare (though it must be explicitly enabled both at compile time and at runtime). Interesting that said sanitizer is conformant to C but not to C++.

> Another could be freedom for compilers how they will layout stack
> variables as you are not allowed to compare addresses of them.

I don't think undefined vs. unspecified makes much of a difference here; the compiler could just always return false to every comparison between pointers to automatic variables and you wouldn't be able to learn anything about the layout.