Date: Tue, 16 Sep 2025 16:45:00 +0200
Am Di., 16. Sept. 2025 um 16:40 Uhr schrieb Andrey Semashev via
Std-Discussion <std-discussion_at_[hidden]>:
> On 16 Sep 2025 17:02, Nate Eldredge via Std-Discussion wrote:
> >
> >> On Sep 16, 2025, at 07:53, Nate Eldredge via Std-Discussion <std-
> >> discussion_at_[hidden]> wrote:
> >>
> >>> On Sep 16, 2025, at 04:33, Andrey Semashev via Std-Discussion <std-
> >>> discussion_at_[hidden]> wrote:
> >>>
> >>> On 15 Sep 2025 16:48, David Brown via Std-Discussion wrote:
> >>>>
> >>>> First ask yourself, is there any reason why you would want to compare
> >>>> unrelated pointers for ordering?
> >>>
> >>> One common use case is testing whether the pointers point to a
> subobject
> >>> of the same object. For example, if a pointer points within a string or
> >>> an array. This check is often needed to properly implement operations
> on
> >>> the string/array, such as selecting the direction of element iteration.
> >>
> >> I don't actually think you can do this even with std::less. It's
> >> defined to use the implementation-defined strict total order over
> >> pointers (https://eel.is/c++draft/defns.order.ptr <https://eel.is/c+
> >> +draft/defns.order.ptr>); that has to be consistent with the <
> >> operator, but no other promises are made. So for instance, given
> >> `char foo[100];`, if we have `std::greater_equal<char *>{}(foo, p) &&
> >> std::less<char *>{}(p, foo+3)`, I don't think the standard allows us
> >> to conclude that `p == foo || p == foo+1 || p == foo+2`. The converse
> >> holds, of course.
> >
> > That should have been `std::greater_equal<char *>{}(p, foo) &&
> > std::less<char *>{}(p, foo+3)`.
>
> Does the standard provide additional guarantees for
> std::greater_equal<T*>? I thought it only did for std::less<T*>.
Yes, since quite a while we have [comparisons.general] p2
"For templates less, greater, less_equal, and greater_equal, the
specializations for any pointer type
yield a result consistent with the implementation-defined strict total
order over pointers (3.28)."
Similar wording exists for the specializations less<void>, greater<void>,
less_equal<void>, and greater_equal<void> if the call operator calls a
built-in operator comparing pointers.
- Daniel
> Which
> means you'd have to write `!std::less<char *>{}(p, foo) &&
> std::less<char *>{}(p, foo+3)`.
>
> Given this, if the condition is true, p *must* point to one of the first
> three elements of foo. I don't see how it can be otherwise.
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
Std-Discussion <std-discussion_at_[hidden]>:
> On 16 Sep 2025 17:02, Nate Eldredge via Std-Discussion wrote:
> >
> >> On Sep 16, 2025, at 07:53, Nate Eldredge via Std-Discussion <std-
> >> discussion_at_[hidden]> wrote:
> >>
> >>> On Sep 16, 2025, at 04:33, Andrey Semashev via Std-Discussion <std-
> >>> discussion_at_[hidden]> wrote:
> >>>
> >>> On 15 Sep 2025 16:48, David Brown via Std-Discussion wrote:
> >>>>
> >>>> First ask yourself, is there any reason why you would want to compare
> >>>> unrelated pointers for ordering?
> >>>
> >>> One common use case is testing whether the pointers point to a
> subobject
> >>> of the same object. For example, if a pointer points within a string or
> >>> an array. This check is often needed to properly implement operations
> on
> >>> the string/array, such as selecting the direction of element iteration.
> >>
> >> I don't actually think you can do this even with std::less. It's
> >> defined to use the implementation-defined strict total order over
> >> pointers (https://eel.is/c++draft/defns.order.ptr <https://eel.is/c+
> >> +draft/defns.order.ptr>); that has to be consistent with the <
> >> operator, but no other promises are made. So for instance, given
> >> `char foo[100];`, if we have `std::greater_equal<char *>{}(foo, p) &&
> >> std::less<char *>{}(p, foo+3)`, I don't think the standard allows us
> >> to conclude that `p == foo || p == foo+1 || p == foo+2`. The converse
> >> holds, of course.
> >
> > That should have been `std::greater_equal<char *>{}(p, foo) &&
> > std::less<char *>{}(p, foo+3)`.
>
> Does the standard provide additional guarantees for
> std::greater_equal<T*>? I thought it only did for std::less<T*>.
Yes, since quite a while we have [comparisons.general] p2
"For templates less, greater, less_equal, and greater_equal, the
specializations for any pointer type
yield a result consistent with the implementation-defined strict total
order over pointers (3.28)."
Similar wording exists for the specializations less<void>, greater<void>,
less_equal<void>, and greater_equal<void> if the call operator calls a
built-in operator comparing pointers.
- Daniel
> Which
> means you'd have to write `!std::less<char *>{}(p, foo) &&
> std::less<char *>{}(p, foo+3)`.
>
> Given this, if the condition is true, p *must* point to one of the first
> three elements of foo. I don't see how it can be otherwise.
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
Received on 2025-09-16 14:45:15