On Sep 15, 2025, at 06:48, Yongwei Wu via Std-Discussion <std-discussion@lists.isocpp.org> wrote:

As per my understanding of the C++ standard, operators like < should not be used to compare unrelated pointers, but function objects like std::less can. Is there any reason why we cannot make p1 < p2 just behave like std::less<T*>{}(p1, p2)? I really cannot think any.

Cost.  std::less may be more expensive than < , and the programmer should not have to pay that cost for the common case of comparing pointers within the same array.

The classic example was x86-16 with the "compact" or "large" code models, in which a data pointer is a "far" pointer consisting roughly of struct { unsigned offset; unsigned segment; };.  (Here `unsigned` is 16 bits.)  A 20-bit linear address is formed by (unsigned long)segment << 4 + offset.

In these code models, every individual array exists within a single segment (and so is limited to 65535 bytes) but distinct arrays may be in different segments.  So p1 < p2 can simply compare the offset parts, because the segments must agree if they point within the same array, which costs one cheap 16-bit compare instruction (cmp si, di).  But std::less<T *>{}(p1, p2) must compute and compare the linear addresses, requiring several shifts and 32-bit adds, and being about an order of magnitude slower and larger.

(I guess most linkers would keep all objects in the low parts of their segments, in which case a lexicographic compare would suffice, which is only twice as expensive.  I don't know if x86-16 C++ implementations actually relied on this behavior.)