C++ Logo

std-discussion

Advanced search

Re: Hostile implementation of strict total order of pointers

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Sun, 23 Jul 2023 17:57:50 +0100
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.

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-23 16:57:57