Date: Thu, 16 Jan 2014 23:21:12 +0100
On 01/16/2014 11:05 PM, Matt Austern wrote:
> That's an interesting possibility that I hadn't considered. It's definitely appealing in some ways, but I think that it, too, would imply some pretty big surgery in some pretty fundamental parts of the standard. So let's consider the following code snippet:
> struct MyPOD { int x; }; // 1
> void* vp = malloc(sizeof(MyPOD)); // 2
> MyPOD* p1 = static_cast<MyPOD*>(vp); // 3
> MyPOD* p2 = new MyPOD; // 4
>
> So the basic question I'd ask is: after line 4, what are you allowed
> to do with p1 and what are allowed to do with p2, and how do the
> answers differ? We've got a couple of choices.
>
> First choice: we decide that you aren't allowed to do anything that
> involves dereferencing p1, since p1 doesn't point to an object.
Please don't confuse "object" with "lifetime".
1.8p1 says an object is a region of storage. Both *p1 and
*p2 satisfy that.
Further, 3.8p1 seems to say that the lifetime of both *p1 and *p2
has begun.
> Second choice: we decide that you're allowed to do just the same
> things with p1 as you are with p2. (Except, of course, that you're
> required to free p1 versus deleting p2.) So *p2 is an object and *p1
> isn't, but you're allowed to use *p1 as if it was an object.
Both are objects, the current C++ wording leaves no doubt about
that.
> I'm still leaning toward thinking that, after line 4, both *p1 and
> *p2 are objects of type MyPOD. I don't know how the standard should
> say that, though. Some change, somewhere, seems called for.
The bug is more that the lifetimes of objects of arbitrary
type T appear to begin per the words in 3.8p1, which seems wrong.
Jens
> That's an interesting possibility that I hadn't considered. It's definitely appealing in some ways, but I think that it, too, would imply some pretty big surgery in some pretty fundamental parts of the standard. So let's consider the following code snippet:
> struct MyPOD { int x; }; // 1
> void* vp = malloc(sizeof(MyPOD)); // 2
> MyPOD* p1 = static_cast<MyPOD*>(vp); // 3
> MyPOD* p2 = new MyPOD; // 4
>
> So the basic question I'd ask is: after line 4, what are you allowed
> to do with p1 and what are allowed to do with p2, and how do the
> answers differ? We've got a couple of choices.
>
> First choice: we decide that you aren't allowed to do anything that
> involves dereferencing p1, since p1 doesn't point to an object.
Please don't confuse "object" with "lifetime".
1.8p1 says an object is a region of storage. Both *p1 and
*p2 satisfy that.
Further, 3.8p1 seems to say that the lifetime of both *p1 and *p2
has begun.
> Second choice: we decide that you're allowed to do just the same
> things with p1 as you are with p2. (Except, of course, that you're
> required to free p1 versus deleting p2.) So *p2 is an object and *p1
> isn't, but you're allowed to use *p1 as if it was an object.
Both are objects, the current C++ wording leaves no doubt about
that.
> I'm still leaning toward thinking that, after line 4, both *p1 and
> *p2 are objects of type MyPOD. I don't know how the standard should
> say that, though. Some change, somewhere, seems called for.
The bug is more that the lifetimes of objects of arbitrary
type T appear to begin per the words in 3.8p1, which seems wrong.
Jens
Received on 2014-01-16 23:21:14