C++ Logo

sg12

Advanced search

Re: [ub] C provenance semantics proposal

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 11 Apr 2019 08:58:15 -0400
On Wed, Apr 10, 2019 at 6:28 PM Jens Maurer <Jens.Maurer_at_[hidden]> wrote:

> On 11/04/2019 00.06, Jens Gustedt wrote:
> > On Wed, 10 Apr 2019 23:40:37 +0200 Jens Maurer <Jens.Maurer_at_[hidden]
> > wrote:
> >>> Inter-object equality comparison has to be supported,
> >>
> >> "Supported" in the sense of "getting a well-defined, stable answer",
> >> I presume. Why do you need that?
> >
> > Because this is all that pointer equality is about. I have to be able
> > to compare pointers to whatever objects for equality. If I can only
> > use it for pointers for which I know that they point to the same
> > object, I don't a need a `==` operator in the language :)
>
> Not quite. It does make sense to compare pointers to subobjects
> within the same larger object,


And also to compare pointers to different objects.

    void somefunc(int n) {
        char local_buffer[100];
        char *p = (n > 100 ? malloc(n) : local_buffer);
        use(p);
        if (p != local_buffer) free(p);
    }

This idiom is supported by standard C and C++ today (that is, equality
comparison of arbitrary pointers is supported today), and there is lots of
code in the wild that relies on this idiom continuing to work. (libstdc++'s
std::string
<https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/basic_string.h#L222>
and libc++'s std::function
<https://github.com/llvm-mirror/libcxx/blob/master/include/functional#L1732>,
for example. But also a lot of industry code.) Any proposal to change C/C++
so that this idiom stops working would be a non-starter IMHO. So it's good
that this "provenance" work doesn't propose to change this aspect of C/C++.

However, I do notice that the above idiom usually doesn't require that
equality comparison work for pointers of different provenance. We just
require that malloc(n) *never* compare equal to local_buffer, and
local_buffer *always* compare equal to local_buffer. We don't, like,
serialize the pointer down into a uintptr_t or a text file and then read it
back in and *then *try to compare it.

>> It seems odd to desire support for equality comparisons, but not
> >> relational ones.
> >
> > Why would that be odd? Relational comparison is much more complex, it
> > assumes a totally ordered address space. Not all architecture have
> > that naturally.
>
> So, let's talk about segmented 16-bit mode of Intel 8086, where
> an object is at most 64 KB (one segment).
>

Intel still has a completely linear address-space; it just represents those
addresses in a weird redundant way at the bit level.

When we talk about an address-space that is not "totally ordered," I
picture an address space something like what Cerberus displays graphically:
it's just a bunch of boxes floating in space, some of which are guaranteed
to be vertically contiguous (that is, ordered) and some of which aren't.
Does my mental model correspond to some real-world
heterogeneous/distributed/associative memory that actually exists, or will
exist in the next 40 years? I honestly don't know. But the "bunch of boxes
floating in space" addressing model is really easy to imagine and draw on a
whiteboard, so I think I understand why it's the model that C and C++ use.


> C is supposed to work on a much larger set of architectures than POSIX,
> > even `uintptr_t` is an optional type in C.
>
> I continue to be slightly puzzled by the insistent mention of "C"
> given that one recipient of the e-mail traffic is a WG21 study group.
> Ignoring the C++ status quo in this area


I don't think it's odd that the WG14 people in this thread talk about "C",
any more than I think it's odd that you and I talk about "C++". Remember
that status quo goes both ways: C++ has borrowed a fair bit from C, too. ;)

–Arthur

Received on 2019-04-11 14:58:28