c++ - Overwriting an object with an object of same type -
is following defined?
#include <iostream> #include <string.h> using namespace std; struct const { const int i; const (int i) : i(i) {} int get0() { return 0; } // best accessor ever! }; int main() { const *q,*p = new const(1); new (p) const(2); memcpy (&q, &p, sizeof p); cout << q->i; return 0; }
note after construction of second const
, p
doesn't semantically (intentionally?) points new object, , first gone, usable "as void*
". second object constructed @ exact same address, bit pattern of p
represents address of new object.
comment
new (p) const(2)
erase old object stored @ p
, pointer not valid anymore, except pointer storage (void*
).
i want recover value of p
const*
.
comment 2
after either p->~const()
or memset (p, 0, sizeof *p)
clear p
not point valid object, p
can used pointer storage (void*
or char*
), example reconstruct object. @ point p->get0()
not allowed.
here demolition of old object done constructor of new one, don't think makes difference.
my intuition that: in case, old object gone, , p
points old object, not new one.
i looking confirmation or refutation based on standard.
see also
i have asked same question pointers, in c , c++ :
- dereferencing out of bound pointer contains address of object (array of array)
- is memcpy of pointer same assignment?
- are pointer variables integers operators or "mystical"?
please read these discussions before answering "this ridiculous".
(making community-wiki incorporating dyp's comment re 3.8/7 significant; while earlier analysis correct have said same things code broken, having overlooked 3.8/7 myself)
const *q,*p = new const(1); new (p) const(2);
the new(p) const(2);
line overwrites object had been constructed const(1)
.
memcpy (&q, &p, sizeof p);
this equivalent q = p;
.
cout << q->i;
this accesses q->i
member, 2
.
the noteworthy things are:
std::memcpy
ugly way assignp
q
... legal though under 3.9/3:
for trivially copyable type
t
, if 2 pointerst
point distinctt
objectsobj1
,obj2
, neitherobj1
norobj2
base-class subobject, if underlying bytes (1.7) makingobj1
copiedobj2
,obj2
shall subsequently hold same valueobj1
. [ example:
t* t1p; t* t2p; // provided t2p points initialized object ... std::memcpy(t1p, t2p, sizeof(t)); // @ point, every subobject of trivially copyable type in *t1p contains // same value corresponding subobject in *t2p
the overwriting of old
const(1)
objectconst(2)
allowed long program doesn't depend on side effects of former's destructor, doesn't.(as dyp noted in comments below) ongoing access
const(2)
object usingp
illegal under 3.8/7's third point:
pointer pointed original object [...] can used manipulate new object, if...
- the type of original object not
const
-qualified, and, if class type, not contain non-static data member typeconst
-qualified or reference type ...
- using
q
- ratherp
- accessi
presumably necessary avoid compiler optimisations based on presumed knowledge ofi
.
as commentary:
note after construction of second
const
,p
doesn't semantically (intentionally?) points new object, , first gone, usable "asvoid*
".
given placement-new object @ address contained in p
, p
point newly created object, , intentionally, can't used manipulate object under 3.8/7 above.
given seem have notion of "semantically pointing" that's not defined in c++ truth of part of statement's in own mind.
'after construction of second const
, p
...is usable "as void*
' makes no sense... it's not more usable beforehand.
but second object constructed @ exact same address, bit pattern of
p
represents address of new object.
of course, comments show think "bit pattern" somehow distinct value of pointer applies assignment =
, not true.
new (p) const(2)
erase old object stored @p
, pointer not valid anymore, except pointer storage (void*
).
"erase" strange term it... overwrites more meaningful. dyp noted , explained above, 3.8/7 says shouldn't "manipulate" object p
points after placement new, value , type of pointer unaffected placmeent new. can call f(void*)
pointer type, placement-new
doesn't need know or care type of p
expression.
after either
p->~const()
ormemset (p, 0, sizeof *p)
clearp
not point valid object,p
can used pointer storage (void*
orchar*
), example reconstruct object. @ pointp->get0()
not allowed.
most of that's true, if "p
can used" mean value of p
@ time rather pointer (which can of course assigned to). , you're trying little clever void*
/ char*
thing - p
remains const*
, if it's used placement new doesn't care pointee type.
"i want recover value of
p
const*
."
the value of p
not changed after first initialised. placement-new
uses value - not modify it. there's nothing recover nothing lost. said, dyp's highlighted need not use p
manipulate object, while value wasn't lost it's not directly usable wanted either.
Comments
Post a Comment