C++ Logo


Advanced search

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

From: Herb Sutter <hsutter_at_[hidden]>
Date: Thu, 16 Jan 2014 20:17:32 +0000
> >> | 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.
> >>
> >> Well, in fact I don't take it obvious that the lifetime of an object
> >> has even begun!
> >> I don't even see that or object has been constructed or initialized.
> >
> > Agreed. I would expect line 4 to be at least unspecified behavior and
> > probably undefined behavior.

OK, let me back this off to just "I would expect that in this code no lifetime of any object has begun."

> I feel like I must have missed part of the conversation.
> We want to utterly break compatibility with C (and C-like C++ code) here?
> struct B { int x };
> struct B* p = (B*) malloc(sizeof(B));
> p->x = 17;

FWIW, std::vector does similarly internally, except it actually calls constructor in-place. I'm fine with that.

What I'm not fine with is the claim that the "lifetime" of anything began here. That doesn't make sense, and it matters to me because lifetime is fundamental.

As I pointed out in other email that might have been delayed by moderation, if in the above code any lifetime began, then we have a contradiction in the standard because we would be in the untenable position that two objects can have the same address:

 struct B { int x };
 void* p = malloc(sizeof(B));

 B* pb = (B*)p;
 pb->x = 17;

 short* ps = (short*)p
 *ps = 17;

None of this code can be viewed as starting a lifetime. Otherwise, proof by contradiction (meaning contradiction in the standard): B and short are both trivially-constructible. If any of these lines start a lifetime of either a B or a short on the grounds that they are trivially-constructible, then this code must start the life of *both* a B and a short, and then *pb and *ps have the same address, which is a contradiction. Therefore none of these lines start a lifetime, QED.

Am I missing something?


Received on 2014-01-16 21:17:39