C++ Logo

SG12

Advanced search

Subject: Re: [ub] type punning through congruent base class?
From: Matt Austern (austern_at_[hidden])
Date: 2014-01-16 12:29:46


On Thu, Jan 16, 2014 at 10:04 AM, Gabriel Dos Reis <gdr_at_[hidden]>wrote:

> Casting a pointer from T* to U*, in and by itself, does not necessarily
> establish or end a lifetime.
>

Indeed. Richard's messages make me a little uneasy about just what does
begin the lifetime of a POD object, though. I'm thinking of:
  struct B { int x; }; // 1
  void* p = malloc(sizeof(B)); // 2
  B* pb = static_cast<B*>(p); //3
  pb->x = 17; // 4

I take it as obvious that the lifetime of an object of type B has begun
somewhere in this code snippet. Now the question is: which specific line
begins that lifetime? As you say, casting a pointer doesn't begin or end a
lifetime; I think we can rule out line 3 as the one that begins the
lifetime of that B object. Line 1 doesn't look too promising either.

A literal reading of the standard ([basic.life]/1) suggests that it's line
2:
"The lifetime of an object of type T begins when:
— storage with the proper alignment and size for type T is obtained, and
— if the object has non-trivial initialization, its initialization is
complete."

In line 2 we have obtained storage with the proper alignment and size for
type B, and the second bullet item doesn't apply since B has no non-trivial
initialization. None of the other lines are relevant to the beginning of
the lifetime.

But that's a little disturbing too. If we've got:
  struct X { int x; }; // 1'
  struct Y { int y; }; // 2'
  void* p = malloc(sizeof(X)); // 3'
then does line 3' mean that the lifetime of some object has begun? Again a
literal reading of that same standard text suggests yes. We have obtained
storage with the proper alignment and size for type X, so the lifetime of
an object of type X has begun. Exactly the same argument means that the
lifetime of an object of type Y has begun, and similarly for every other
type, mentioned or not, whose size is equal to sizeof(X).

That seems like a crazy conclusion, but I don't see how to reject it
without also rejecting the idea that the lifetime of an object of type B
has been established somewhere in my first code snippet. What all of this
suggests to me is that the concept of object lifetime needs a little more
thought for types that don't have initialization.

                         --Matt



SG12 list run by herb.sutter at gmail.com