C++ Logo

std-discussion

Advanced search

Re: Hostile implementation of strict total order of pointers

From: Will Hawkins <hawkinsw_at_[hidden]>
Date: Sun, 23 Jul 2023 23:11:56 -0400
On Sun, Jul 23, 2023 at 12:57 PM Lénárd Szolnoki <cpp_at_[hidden]> wrote:
>
> On Sun, 2023-07-23 at 01:37 -0400, Will Hawkins via Std-Discussion
> wrote:
> > On Sat, Jul 22, 2023 at 2:47 PM Brian Bi via Std-Discussion
> > <std-discussion_at_[hidden]> wrote:
> > >
> > >
> > >
> > > On Sat, Jul 22, 2023 at 2:40 PM Lénárd Szolnoki via Std-Discussion
> > > <std-discussion_at_[hidden]> wrote:
> > > >
> > > > Hi,
> > > >
> > > > Given these two arrays, each being a complete object:
> > > >
> > > > int a[2];
> > > > int b[2];
> > > >
> > > > The partial ordering of the addresses (defined by the operator <)
> > > > of
> > > > the int objects within is:
> > > >
> > > > 1. &a[0] < &a[1]
> > > > 2. &b[0] < &b[1]
> > > >
> > > > A hostile strict total order that is consistent with this is
> > > > &a[0] < &b[0] < &a[1] < &b[1].
> > > >
> > > > Is there wording that prevents the implementation defined strict
> > > > total
> > > > order to manifest like this?
> > >
> > >
> > > Not as far as I can tell.
> >
> > Does the last clause of https://eel.is/c++draft/intro.object#9 have
> > anything to say about this situation?
> >
> > ... otherwise, they have distinct addresses and occupy disjoint bytes
> > of storage."
>
> It doesn't. Just because the addresses are interleaved according to
> pointer comparison, it doesn't mean that they are also interleaved
> according to contiguity, i.e. pointer arithmetic.
>
> Consider the following (admittedly hostile) implementation:
>
> The address space is segmented, the segments are disjoint, complete
> objects always fully reside within a single segment.
>
> The < operator compares pointers based on their offsets only.
>
> std::less compares pointers by offset first, segment second (this is
> the weird and hostile one).
>
> char a[2]; // placed at segment 1, offset 1
> char b[2]; // placed at segment 2, offset 1
>
> The char elements compare in the following order according to
> std::less:
>
> 1. &a[0] (offset 1, segment 1)
> 2. &b[0] (offset 1, segment 2)
> 3. &a[1] (offset 2, segment 1)
> 4. &b[1] (offset 2, segment 2)
>
> I don't think the standard rules out such an odd implementation, but I
> think it should.

It seems like expr.rel.4 (in particular, expr.rel.4.3) explicitly
allows this situation:

4 [1]
The result of comparing unequal pointers to objects is defined in
terms of a partial order consistent with the following rules:

(4.1)
If two pointers point to different elements of the same array, or to
subobjects thereof, the pointer to the element with the higher
subscript is required to compare greater.
(4.2)
If two pointers point to different non-static data members of the same
object, or to subobjects of such members, recursively, the pointer to
the later declared member is required to compare greater provided
neither member is a subobject of zero size and their class is not a
union.
(4.3)
Otherwise, neither pointer is required to compare greater than the other.

Sincerely,
Will

[1] https://eel.is/c++draft/expr.rel#4
>
> Cheers,
> Lénárd
> >
> > Sincerely,
> > Will
> >
> > >
> > > >
> > > >
> > > > One problem with this is that std::less is commonly used to check
> > > > if a
> > > > given pointer points within a range. If such a manifestation is
> > > > possible then such usages are incorrect (or at least
> > > > theoretically not
> > > > portable).
> > >
> > >
> > > I agree that this is something that should be banned. To be
> > > specific, `&a[0] < &b[0] < &a[1] < &b[1]` is probably the sort of
> > > thing that is supposed to be allowed, because the idea behind `<`
> > > not being a total order is to support segmented architectures where
> > > e.g. it might only compare the offset part of the address. But
> > > `std::less` always has to take into account both the segment and
> > > offset, so I can't see any reason why it should be allowed to give
> > > this "hostile" order.
> > >
> > > >
> > > >
> > > > Cheers,
> > > > Lénárd
> > > >
> > > > P.S. Someone pointed this out to me on the #include <C++>
> > > > discord.
> > > > --
> > > > Std-Discussion mailing list
> > > > Std-Discussion_at_[hidden]
> > > > https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
> > >
> > >
> > >
> > > --
> > > Brian Bi
> > > --
> > > Std-Discussion mailing list
> > > Std-Discussion_at_[hidden]
> > > https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>

Received on 2023-07-24 03:12:08