c++ - Unrestricted union in practice -


i have questions unrestricted unions , application in practice. let's suppose have following code :

struct mystruct {     mystruct(const std::vector<int>& a) : array(a), type(array)     {}     mystruct(bool b) : boolean(b), type(bool)     {}     mystruct(const mystruct& ms) : type(ms.type)     {         if (type == array)             new (&array) std::vector<int>(ms.array);         else             boolean = ms.boolean;     }     mystruct& operator=(const mystruct& ms)     {         if (&ms != this) {             if (type == array)                 array.~vector<int>(); // edit(2)              if (ms.type == array)                 new (&array) std::vector<int>(ms.array);             else                 boolean = ms.boolean;             type = ms.type;         }         return *this;     }     ~mystruct()     {         if (type == array)             array.~vector<int>();     }      union {         std::vector<int> array;         bool             boolean;     };     enum {array, bool} type; }; 
  1. is code valid :) ?
  2. is necessary explicitly call vector destructor each time using boolean (as stated here http://cpp11standard.blogspot.com/2012/11/c11-standard-explained-1-unrestricted.html)
  3. why placement new required instead of doing 'array = ms.array' ?

edit:

  • yes, compiles
  • "members declared inside anonymous unions members of containing class, , can initialized in containing class's constructor." (c++11 anonymous union non-trivial members)
  • adding explicit destructors suggested, leads sigsev g++ 4.8 / clang 4.2

  1. the code's buggy: change array.clear(); array.~vector<int>();

explanation: operator= using placement new on object hasn't been destructed, practically can expect leak dynamic memory previous array had been using (clear() doesn't release memory / change capacity, destructs elements , changes size).

from 9.5/2:

if non-static data member of union has non-trivial default constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move assignment operator (12.8), or destructor (12.4), corresponding member function of union must user-provided or implicitly deleted (8.4.3) union.

so, vector constructor, destructor etc never kicks in themselves: must call them explicitly when wanted.

in 9.5/3 there's example:

consider following union:

union u {     int i;     float f;     std::string s; }; 

since std::string (21.3) declares non-trivial versions of of special member functions, u have implicitly deleted default constructor, copy/move constructor, copy/move assignment operator, , destructor. use u, or of these member functions must user-provided.

that last bit - "to use u, or of these member functions must user-provided." - seems presume u needs coordinate own vaguely value-semantic behaviour, in case surrouding struct doing don't need define of these union member functions.

2: must call array destructor whenever array value being replaced boolean value. if in operator= new array value being placement-newed instead of assigned, old array must have destructor called, using operator= more efficient when existing memory sufficient elements being copied. basically, must match constructions , destructions. update: example code has bug per comment below.

3: why placement new required instead of doing 'array = ms.array' ?

array = ms.array invokes std::vector<int>::operator= assumes this pointer addresses constructed object. inside object can expect there pointer either null or refer internal short-string buffer, or refer heap. if object hasn't been destructed, operator= may call memory deallocation function on bogus pointer. placement new says "ignore current content of memory object occupy, , construct new object valid members scratch.


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -