C++ Logo

SG12

Advanced search

Subject: Re: [ub] type punning through congruent base class?
From: Richard Smith (richardsmith_at_[hidden])
Date: 2014-01-16 16:55:12


On 16 January 2014 14:39, Gabriel Dos Reis <gdr_at_[hidden]> wrote:

> I had always assumed that you were always mindful of that paragraph –
> which explains part of my puzzlement at your previous claims. It is so
> central the entire C++ object model. Thanks for clarifying.
>
>
>
> We may have to tweak this paragraph, but I don’t think the root cause is
> here. It is elsewhere – the very paragraph under discussion in previous
> messages.
>
>
>
> By the way, my concern isn’t driven by theory. I would like to make sure
> that future high quality C++ implementations can actually include
> instrumentation of lifetime and aliasing issues – the way implementations
> currently do with “address sanitizers”, “signed integer arithmetic
> overflow”, etc.
>

That's also my goal; I started digging into this precisely because I was
designing an object lifetime sanitizer -- this very rapidly led to the
observation that the model described in 1.8/1 is untenable as a basis for
such a sanitizer, because it does not match the model used by programmers
and implementers -- such a sanitizer would diagnose problems in a large
quantity of real code, in which people assume they can obtain appropriate
storage any way they like, and use it as an object of type T, so long as T
is suitably trivial.

  *From:* ub-bounces_at_[hidden] [mailto:ub-bounces_at_[hidden]] *On
> Behalf Of *Richard Smith
> *Sent:* Thursday, January 16, 2014 1:48 PM
>
> *To:* WG21 UB study group
> *Subject:* Re: [ub] type punning through congruent base class?
>
>
>
> On 16 January 2014 13:10, Herb Sutter <hsutter_at_[hidden]> wrote:
>
> > > | > Well, as far as I understand, trivial constructors might not be
> called at all.
> > > |
> > > | Maybe "might not be called" is part of the bug then. Isn't the right
> > > | model that trivial ctors are called, but "might do nothing"?
> > >
> > > Yes, agreed.
> >
> > That may be part of a proposed model, but it's not part of the existing
> model,
> > which (for compatibility) is based on C's model, where fields of a
> (necessarily
> > trivially-constructible) struct can be written to as soon as suitable
> memory for
> > that struct is obtained.
>
> Ah, I see the problem, thanks James and Daveed. Let me try to summarize
> what I've learned so far.
>
> In C++, "storage" and "lifetime" don't mean the same thing for a
> non-trivially-constructible type.
>
> But in C the word "lifetime" has a different meaning than C++. I have C99
> handy, but it should be the same in C11, and "lifetime" and "storage
> duration" are the same thing in C:
>
> 6.2.4/1: An object has a storage duration that determines its
> lifetime. There are three storage durations: static, automatic, and
> allocated. Allocated storage is described in 7.20.3.
>
> 6.2.4/2: The lifetime of an object is the portion of program
> execution during which storage is guaranteed to be reserved for it.
>
> 7.20.3: The order and contiguity of storage allocated by
> successive calls to the calloc, malloc, and realloc functions is
> unspecified. The pointer returned if the allocation succeeds is suitably
> aligned so that it may be assigned to a pointer to any type of object and
> then used to access such an object or an array of such objects in the space
> allocated (until the space is explicitly deallocated). The lifetime of an
> allocated object extends from the allocation until the deallocation. Each
> such allocation shall yield a pointer to an object disjoint from any other
> object. The pointer returned points to the start (lowest byte address) of
> the allocated space.
>
> But one thing that follows here is that in C, "the object" is the raw
> memory. Right? This follows from the above three quotes.
>
>
> So is that different in C++?
>
>
>
> There's one other rule that I'd overlooked in my prior messages.
> [intro.object]/1 presents this beautiful model: "An object is a region of
> storage. [...] An object is created by a definition (3.1), by a
> new-expression (5.3.4) or by the implementation (12.2) when needed.[...] An
> object has a storage duration (3.7) which influences its lifetime (3.8). An
> object has a type (3.9)."
>
>
>
> Trouble is, this model gives a vast quantity of real-world C++ code
> undefined behavior, including any C-like code that uses the 'malloc'
> technique described in this thread. This breaks compatibility with C and
> with real-world C++ so thoroughly that I think it's not a tenable position,
> and that the rule must be revised. Prior to this thread, I had assumed that
> we would easily reach consensus on that, but it seems that's not the case.
>
>
>
> As Daveed pointed out:
>
>
> > > Am I missing something?
> >
> > I think so: 3.8/1 also says that the lifetime of an object ends if its
> storage is
> > reused
>
> "...or released" -- okay. I always thought reused meant deallocated and
> reallocated, but since it says "reused or released" it does seem to follow
> that reused means what Daveed said:
>
> > . So when you write to *ps, you've terminated the lifetime of *pb.
>
> OK, that's C++. The word "reused" doesn't appear anywhere in the C99
> standard at least.
>
>
> Trying to summarize:
>
> So was the goal of the 3.8/1 wording of "reuse" to acknowledge (and be
> compatible with) the C memory-scribbling, while still being able to say
> that even for raw storage and PODs a given piece of storage has a
> well-defined type at any given point in time (namely the one it was last
> written to as)? And does "reused" clearly say that "written-to" part if
> that's the intent?
>
> And so for raw memory and PODs, storage as a type T begins when you read
> or write it as a T, and ends when you read or write as some other type U,
> as long as T and U are PODs that fit in the storage (incl. size and
> alignment)?
>
> And dare I ask: Um, what about using part of the same allocated buffer to
> hold a T and another part to hold a U, such as malloc(1000) and read/write
> an int at offset 10 and read/write a short at offset 314 -- they're the
> same allocation, so do we even have any way to talk about that?
>
> Herb
>
>
> _______________________________________________
> ub mailing list
> ub_at_[hidden]
> http://www.open-std.org/mailman/listinfo/ub
>
>
>
> _______________________________________________
> ub mailing list
> ub_at_[hidden]
> http://www.open-std.org/mailman/listinfo/ub
>



SG12 list run by herb.sutter at gmail.com