c++ - Active member of an union, uniform initialization and constructors -


as (working draft of) c++ standard says:

9.5.1 [class.union]

in union, @ one of non-static data members can active @ time, is, value of @ 1 of non-static data members can stored in union @ time. [...] size of union sufficient contain largest of non-static data members. each non-static data member allocated if sole member of struct. non-static data members of union object have same address.

but don't know how identify active member of union , i'm not used enough dive standard locate standard says it, i've tried figure how active member setted i've found how swapped:

9.5.4 [class.union]

[ note: in general, 1 must use explicit destructor calls , placement new operators change active member of union. —end note ] [example: consider object u of union type u having non-static data members m of type m , n of type n. if m has non-trivial destructor , n has non-trivial constructor (for instance, if declare or inherit virtual functions), active member of u can safely switched m n using destructor , placement new operator follows:

u.m.~m(); new (&u.n) n; 

end example ]

so guess active member of union 1 first asigned, used, constructed or placement-new'ed; becomes kind of tricky uniform initialization, consider following code:

union foo {     struct {char a,b,c,d;};     char array[4];     int integer; };  foo f; // default ctor std::cout << f.a << f.b << f.c << f.d << '\n'; 

which active member of union on code above? std::cout reading active member of union? code below?

foo f{0,1,2,3}; // uniform initialization std::cout << f.a << f.b << f.c << f.d << '\n'; 

with lines above can initialize nested anonymous struct or either array, if provide integer can initialize foo::a or foo::array or foo::integer... 1 active member?

foo f{0}; // uniform initialization std::cout << f.integer << '\n'; 

i guess active member aninymous struct in of above cases i'm not sure.

if want activate 1 or other union member, should provide constructor activating it?

union bar {     // #1 activate anonymous struct     bar(char x, char y, char z, char t) : a(x),b(y),c(z),d(t) {}     // #2 activate array     bar(char (&a)[4]) { std::copy(std::begin(a), std::end(a), std::begin(array)); }     // #3 activate integer     bar(int i) : integer(i) {}      struct {char a,b,c,d;};     char array[4];     int integer; }; 

i'm sure #1 , #3 mark active union anonymous struct , integer don't know #2 because in moment reach body of constructor members constructed! calling std::copy on inactive union member?

questions:

  • which active union members of foo if constructed following uniform initialization:
    • foo{};
    • foo{1,2,3,4};
    • foo{1};
  • in #2 constructor of bar bar::array active union member?
  • where in standard can read active union member , how set without placement new?

your concern lack of rigorous definition of the active member of union shared (at least of) members of standardization committee - see latest note (dated may 2015) in description of active issue 1116:

we never active member of union is, how can changed, , on. [...]

i think can expect sort of clarification in future versions of working draft. note indicates best have far note in paragraph quoted in question, [9.5p4].

that being said, let's @ other questions.

first of all, there no anonymous structs in standard c++ (only anonymous unions); struct {char a,b,c,d;}; give warnings if compiled reasonably strict options (-std=c++1z -wall -wextra -pedantic clang , gcc, example). going forward, i'll assume have declaration struct { char a, b, c, d; } s; , else adjusted accordingly.

the implicitly defaulted default constructor in first example doesn't perform initialization according [12.6.2p9.2]:

in non-delegating constructor, if given potentially constructed subobject not designated mem-initializer-id (including case there no mem-initializer-list because constructor has no ctor-initializer),

(9.1) - if entity non-static data member has brace-or-equal-initializer , either

(9.1.1) - constructor’s class union (9.5), , no other variant member of union designated mem-initializer-id or
(9.1.2) - constructor’s class not union, and, if entity member of anonymous union, no other member of union designated mem-initializer-id,

the entity initialized specified in 8.5;

(9.2) - otherwise, if entity anonymous union or variant member (9.5), no initialization performed;

(9.3) - otherwise, entity default-initialized (8.5).

i suppose f has no active member after default constructor has finished executing, don't know of standard wording indicates that. can said in practice makes no sense attempt read value of of f's members, since they're indeterminate.

in next example, you're using aggregate initialization, reasonably well-defined unions according [8.5.1p16]:

when union initialized brace-enclosed initializer, braces shall contain initializer-clause first non-static data member of union. [ example:

union u { int a; const char* b; };  u = { 1 };  u b = a;  u c = 1;               // error  u d = { 0, "asdf" };   // error  u e = { "asdf" };      // error  

end example ]

that, brace elision initialization of nested struct, specified in [8.5.1p12], makes struct active member. answers next question well: can initialize first union member using syntax.

your next question:

if want activate 1 or other union member, should provide constructor activating it?

yes, or brace-or-equal-initializer 1 member according [12.6.2p9.1.1] quoted above; this:

union foo {     struct { char a, b, c, d; } s;     char array[4];     int integer = 7; };  foo f; 

after above, active member integer. of above should answer question #2 (the members not constructed when reach body of constructor - #2 fine well).

wrapping up, both foo{} , foo{1} perform aggregate initialization; they're interpreted foo{{}} , foo{{1}}, respectively, (because of brace elision), , initialize struct; first 1 sets struct members 0 , second 1 sets first member 1 , rest 0, according [8.5.1p7].


all standard quotes current working draft, n4527.


paper n4430, deals related issues, hasn't been integrated working draft yet, provides definition active member:

in union, non-static data member active if name refers object lifetime has begun , has not ended ([basic.life]).

this passes buck definition of lifetime in [3.8], has few issues open against it, including aforementioned issue 1116, think we'll have wait several such issues resolved in order have complete , consistent definition. definition of lifetime stands doesn't seem quite ready.


Comments

Popular posts from this blog

searchKeyword not working in AngularJS filter -

sequelize.js - Sequelize: sort by enum cases -

user interface - how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter -