c++ - Accessing inactive union member and undefined behavior? -


i under impression accessing union member other last 1 set ub, can't seem find solid reference (other answers claiming it's ub without support standard).

so, undefined behavior?

the confusion c explicitly permits type-punning through union, whereas c++ () has no such permission.

6.5.2.3 structure , union members

95) if member used read contents of union object not same member last used store value in object, appropriate part of object representation of value reinterpreted object representation in new type described in 6.2.6 (a process called ‘‘type punning’’). might trap representation.

the situation c++:

9.5 unions [class.union]

in union, @ 1 of non-static data members can active @ time, is, value of @ 1 of non-static data members can stored in union @ time.

c++ later has language permitting use of unions containing structs common initial sequences; doesn't permit type-punning.

to determine whether union type-punning is allowed in c++, have search further. recall normative reference c++11 (and c99 has similar language c11 permitting union type-punning):

3.9 types [basic.types]

4 - object representation of object of type t sequence of n unsigned char objects taken object of type t, n equals sizeof(t). value representation of object set of bits hold value of type t. trivially copyable types, value representation set of bits in object representation determines value, 1 discrete element of implementation-defined set of values. 42
42) intent memory model of c++ compatible of iso/iec 9899 programming language c.

it gets particularly interesting when read

3.8 object lifetime [basic.life]

the lifetime of object of type t begins when: — storage proper alignment , size type t obtained, , — if object has non-trivial initialization, initialization complete.

so primitive type (which ipso facto has trivial initialization) contained in union, lifetime of object encompasses @ least lifetime of union itself. allows invoke

3.9.2 compound types [basic.compound]

if object of type t located @ address a, pointer of type cv t* value address said point object, regardless of how value obtained.

assuming operation interested in type-punning i.e. taking value of non-active union member, , given per above have valid reference object referred member, operation lvalue-to-rvalue conversion:

4.1 lvalue-to-rvalue conversion [conv.lval]

a glvalue of non-function, non-array type t can converted prvalue. if t incomplete type, program necessitates conversion ill-formed. if object glvalue refers not object of type t , not object of type derived t, or if object uninitialized, program necessitates conversion has undefined behavior.

the question whether object non-active union member initialized storage active union member. far can tell, not case , although if:

  • a union copied char array storage , (3.9:2), or
  • a union bytewise copied union of same type (3.9:3), or
  • a union accessed across language boundaries program element conforming iso/iec 9899 (so far defined) (3.9:4 note 42), then

the access union non-active member is defined , defined follow object , value representation, access without 1 of above interpositions undefined behaviour. has implications optimisations allowed performed on such program, implementation may of course assume undefined behaviour not occur.

that is, although can legitimately form lvalue non-active union member (which why assigning non-active member without construction ok) considered uninitialized.


Comments

Popular posts from this blog

javascript - backbone.js Collection.add() doesn't `construct` (`initialize`) an object -

php - Get uncommon values from two or more arrays -

Adding duplicate array rows in Php -