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++ :

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 assign p q... legal though under 3.9/3:

for trivially copyable type t, if 2 pointers t point distinct t objects obj1 , obj2, neither obj1 nor obj2 base-class subobject, if underlying bytes (1.7) making obj1 copied obj2, obj2 shall subsequently hold same value obj1. [ 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) object const(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 using p 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 type const-qualified or reference type ...
  • using q - rather p - access i presumably necessary avoid compiler optimisations based on presumed knowledge of i.

as commentary:

note after construction of second const, p doesn't semantically (intentionally?) points new object, , first gone, usable "as void*".

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

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

Popular posts from this blog

dns - How To Use Custom Nameserver On Free Cloudflare? -

python - Pygame screen.blit not working -

c# - Web API response xml language -