C++ Logo

std-discussion

Advanced search

Re: Hostile implementation of strict total order of pointers

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Sun, 23 Jul 2023 18:43:55 +0200
On Sun, Jul 23, 2023, 18:27 Richard Hodges <hodges.r_at_[hidden]> wrote:

>
>
> On Sun, 23 Jul 2023 at 18:09, Edward Catmur <ecatmur_at_[hidden]>
> wrote:
>
>>
>>
>> On Sun, Jul 23, 2023, 17:46 Richard Hodges <hodges.r_at_[hidden]> wrote:
>>
>>>
>>>
>>> On Sun, 23 Jul 2023 at 17:39, Edward Catmur <ecatmur_at_[hidden]>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Sun, Jul 23, 2023, 17:16 Richard Hodges <hodges.r_at_[hidden]> wrote:
>>>>
>>>>> In the light of the C++ memory model being specified in terms of a
>>>>> virtual machine, it seems an anomaly to me that the memory model is not
>>>>> also specified in terms of a linear address space.
>>>>>
>>>>> In this model, segmentation would be merely an implementation detail.
>>>>> This would remove an enormous amount of unnecessary confusion from the
>>>>> language.
>>>>>
>>>>> If people wanted to work in terms of small segments or paged program
>>>>> memory, that is surely something that should be covered by compiler
>>>>> extensions, no?
>>>>>
>>>>
>>>> But would that mean that every pointer is reachable from every other
>>>> pointer?
>>>>
>>>
>>> The language is full of constructs to allow pointers to reach when they
>>> “shouldn’t”. Reinterpret_casr, launder, etc.
>>>
>>> I’m ok with this, and I’m OK with it being easier to work with memory.
>>>
>>
>> I don't really see launder as the same kind of thing. If by
>> reinterpret_cast you mean performing arithmetic in uintptr_t, then by doing
>> so you're explicitly eschewing guardrails and optimization opportunities.
>>
>> And uintptr_t is the escape hatch here. Perhaps making that conversion
>> more tied down would be the way to go, if we can be certain that the
>> translation places the address part ends up in the low bits. And then if we
>> could be sure that std::less is consistent with uintptr_t, non hostility
>> would naturally result.
>>
>>
>>> It seems that might be detrimental to correctness, security and/or
>>>> optimization.
>>>>
>>>
>>> I’m not proposing to remove wording describing the behaviour of aliased
>>> pointers.
>>>
>>
>> I'm not sure what you mean by this. Would a tagged pointer architecture
>> where subtracting or comparing pointers with different tags faults still be
>> permitted? Because that's what I'm most concerned we might lose with a
>> switch to a flat model, along with the possibility of sanitizers to pretend
>> a tagged architecture for identifying bugs, and optimizers to pretend one
>> for the performance benefit.
>>
>>
> There is no slippery slope here.
>
> The ambiguous and convoluted memory model in C++ was standardised because
> at the time the majority of software was written on 80x86 architectures,
> which had a choice of 4 (from memory) memory models. From a high level
> programming perspective, two of them were ridiculous.
>
> I am simply saying that I think that in hindsight, the committee took a
> wrong turn. Had the memory model been standardised to be flat (i.e. the
> huge model in 80x86 land) then today we would be able to compare addresses
> without jumping through hoops,
>

But those hoops are necessary to distinguish the case of comparing pointers
believed to be into the same object from the case of comparing pointers
that might be into different objects. If we didn't have those hoops, how
would we tell whether comparing pointers into different objects is intended
or is a bug?

and we would have no need of the ever-troublesome allocator concept. These
> were invented solely to circumvent the ill-conceived memory model. They are
> a band-aid to fix a malformed skeleton.
>
> If people really wanted to select individual segments, they could have
> carried on using compiler extensions, which they had to anyway, because
> near and far (etc) are not C++ keywords.
>
> I see no problem with tagging memory and tracking lifetimes. Neither do I
> see a difficulty with doing so within a linear memory model.
>
>
>>
>>
>>>
>>>>
>>>>
>>>>> On Sun, 23 Jul 2023 at 08:27, Edward Catmur via Std-Discussion <
>>>>> std-discussion_at_[hidden]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Sun, 23 Jul 2023 at 06:37, Will Hawkins via Std-Discussion <
>>>>>> std-discussion_at_[hidden]> 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."
>>>>>>>
>>>>>>
>>>>>> "Disjoint" just means that incrementing a pointer to the first byte
>>>>>> of one object through to the last byte of that object will not yield a
>>>>>> pointer to a byte of the other object.
>>>>>>
>>>>>> The "hostile std::less<>" posited would have p R q and q R p+1 for
>>>>>> some byte pointer p - that is, q is ordered between p and p+1 even though p
>>>>>> and p+1 point to adjacent bytes of storage.
>>>>>>
>>>>>> Recall that std:less<> is just a strict total order that linearly
>>>>>> extends each strict partial order on the pointers to objects and storage.
>>>>>> There's nothing at present to say that it respects disjointedness of
>>>>>> distinct objects.
>>>>>>
>>>>>> 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
>>>>>>> --
>>>>>>> Std-Discussion mailing list
>>>>>>> Std-Discussion_at_[hidden]
>>>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>>>>>
>>>>>> --
>>>>>> Std-Discussion mailing list
>>>>>> Std-Discussion_at_[hidden]
>>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>>>>
>>>>> --
>>>>> Richard Hodges
>>>>> hodges.r_at_[hidden]
>>>>> office: +44 2032 898 513
>>>>> home: +376 861 195
>>>>> mobile: +376 380 212
>>>>>
>>>>> --
>>> Richard Hodges
>>> hodges.r_at_[hidden]
>>> office: +44 2032 898 513
>>> home: +376 861 195
>>> mobile: +376 380 212
>>>
>>>

Received on 2023-07-23 16:44:09