Why union static members not stored as a union?

狂风中的少年 提交于 2020-02-15 10:44:26

问题


In C++ union can contain static members which, as in the case of classes, belong to a class and therefore are common to all objects.

union U
{
   long l;
   int i;
   static long sl;
   static int si;
};

int U::si;
long U::sl;

It would be logical to expect that all the union static members stored at the same address similar to non-static members storing. But it is not. A simple example shows that static members are stored under different addresses and can contain independent values.

int main()
{
   U u;
   u.si = 10;
   u.sl = 50;

   std::cout << "Non-static members adresses: " << &u.i << " " << &u.l << std::endl;
   std::cout << "Static members adresses: " << &u.si << " " << &u.sl << std::endl;
   std::cout << "Static members values: " << u.si << " " << u.sl << std::endl;
   return 0;
}

Output:

Non-static members adresses: 006FF8EC 006FF8EC
Static members adresses: 00AEB144 00AEB140
Static members values: 10 50

I do not understand why independent values storing was left in unions. I think this is misleading and makes no sense. Nevertheless, it seems to me that there are reasons for this. What purpose of union static members?


回答1:


You can look at this from two perspectives.

The C++ Perspective:

A union is, first and foremost, a class. It has a purpose distinct from a class, but it is informed by what a class is.

A union is a class for which only one of its subobjects is active at any one type. To this end, it changes how member subobjects of unions work. This is also part of why unions can't have base class subobjects.

Static data members are not member subobjects, so their disposition in a union should be no different from their disposition in a non-union class.

Furthermore, static members of types in C++ are really just a scoping mechanism for function and object names. They're still effectively global, but they can be private and hidden, and they have to be prefixed by their typename in order for you to use them.

It doesn't really make sense for static data members of a union to behave any differently from static data members of a class.

The C++-must-be-compatible-with-C Perspective:

Unions exist in C, so C++ has to have them too. But unions are difficult to define within the C++ object model, painful to work with, and a lot of other things. So you can think of unions as a thing that C++ needs to have but would rather not deal with. So how do you deal with them?

You make unions work like C when dealing with the way C unions work. There is no such thing in C as a static member, so there's no C code out there expecting static union members to be combined. Therefore... don't combine them. If the user genuinely needs a static member that is a union of some set of types, they can easily create a union and make a single static member of that type.

So the user doesn't lose any expressive power by making static members different.




回答2:


Unions are classes that hold at most one data member at a time [basic.compound]p1.6 [class]p7 [class.union], and there are no special rules for their static data members w.r.t. the rest of class types (i.e. class and struct).

Therefore, the static data members behave the same as in all classes.

If you want to have a static data member that is the union of several types, you could do something like:

union U {
    long l;
    int i;

    union {
        long l;
        int i;
    } static s;
};

decltype(U::s) U::s;

// They are the same indeed
static_assert(&U().s.l == &U().s.l);

You will need to refer to the elements via s, e.g. s.l instead of sl, though.



来源:https://stackoverflow.com/questions/55540587/why-union-static-members-not-stored-as-a-union

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!