C++ Logo


Advanced search

Re: [ub] *** GMX Spamverdacht *** Re: type punning through congruent base class?

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Thu, 16 Jan 2014 23:06:09 +0100
On 01/16/2014 10:10 PM, Herb Sutter 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.

Yes, except we're mostly not talking about these here.

> But in C the word "lifetime" has a different meaning than C++.

For the subset of C++ that uses only PODs, the meaning
of "lifetime" is supposed to be the same, in my understanding.

> 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.

That corresponds to the "reused or released" phrasing in C++.

> 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.

Same in C++: 1.8p1: "An object is a region of storage."

> So was the goal of the 3.8/1 wording of "reuse" to acknowledge (and
> be compatible with) the C memory-scribbling,

That's my understanding.

> 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?

Well, "reused" is just used to specify that the lifetime of an
object ends. It doesn't say that the lifetime of another object
necessarily starts.

> And so for raw memory and PODs, storage as a type T begins when you

That part doesn't make sense to me. I'm going to read "storage as
a type T" as "lifetime of an object of POD-type T", and ignore the
mentioning of PODs earlier in the sentence.

> 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)?

As far as I understand, that's the intent, in both C and C++.

> 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?

They're the same allocation, but different regions of storage, so
you're fine, in my opinion. (Implementing your own sub-allocators
with a malloc backend probably depends on this to work.)

Your particular example might have alignment issues, though, since
offset 10 is probably misaligned for an "int", and offset 314 might
be misaligned for a "short".


Received on 2014-01-16 23:11:14