Question

Minimal code example:

struct B { 
  union U {
    struct S {} s;
    int i = 100;
  }
  u;  
};

Now if we declare a B obj; then the obj.u.i is assigned a garbage value instead of 100. See the demo here. (The garbage value differs based on optimization flags etc.).

Is the "In class initialization" feature supposed to work with unions.

  • If yes, then what is the correct syntax? Or is this a g++ bug?
  • If not then what int i = 100; does?
Was it helpful?

Solution

This looks like a GCC bug. The standard says (9.5p2):

At most one non-static data member of a union may have a brace-or-equal-initializer.

Otherwise, the rules are the same as for a regular class.

EDIT: In addition, 12.6.2p8:

In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then

  • if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;
  • otherwise, if the entity is a variant member (9.5), no initialization is performed;
  • otherwise, the entity is default-initialized (8.5).

Presumably the implicitly defined default constructor counts here. The i member meets the criteria in the first bullet point, so it's initialized like it were a regular class member. The s member matches the second bullet point, so it's left uninitialized.

OTHER TIPS

I think it is like that because a union reunites more than one element. Below is the work around syntax:

struct B { 
  union U {
    int i;
  }
  u {100};  
};

int main () {
  B obj;
  std::cout << "obj.u.i = " << obj.u.i << "\n";
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top