Topic: Are "empty" classes safe in unions with data?


Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/05/11
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

> Given that objects of "empty" classes [snip] still need memory,
> [snip] I got the idea to conserve space by putting them into an
> union with a data member, f.ex:

> class A { union { X x; int data; }; ...  };

> Now my question: Does the standard guarantee that calls to member
> functions of x don't affect the value of data?

Nope.  In fact, it states that only one data member can be active at
any time, so, if you initialize `data', accessing `x' is undefined.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/05/13
Raw View
Christopher Eltschka wrote:
>
> Given that objects of "empty" classes (that is, classes with no
> data members, no virtual functions and no virtual or non-empty
> base classes) still need memory, and that inheritance from them
> is not always what you want, I got the idea to conserve space by
> putting them into an union with a data member, f.ex:
>
> struct X
> {
>   void f();
>   int g(int);
>   typedef X* pointer;
> };
>
> class A
> {
>   union
>   {
>     X x;
>     int data;
>   };
> ...
> };

The language lawyers will tell you no, but I can't imagine any
reasonable mechanism that a compiler would find useful that would
prevent it from working.

Note that if X is a base class of A, rather than a member, it is
explicitly allowed by the standard to take no space.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/13
Raw View
Alexandre Oliva wrote:
>
> Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
>
> > Given that objects of "empty" classes [snip] still need memory,
> > [snip] I got the idea to conserve space by putting them into an
> > union with a data member, f.ex:
>
> > class A { union { X x; int data; }; ...  };
>
> > Now my question: Does the standard guarantee that calls to member
> > functions of x don't affect the value of data?
>
> Nope.  In fact, it states that only one data member can be active at
> any time, so, if you initialize `data', accessing `x' is undefined.

Does that include taking the address of x? (Since x has no data,
all member functions may be static, so there's no need to access x
in any way except maybe taking the address.)

Since X doesn't have any non-POD data member (indeed, it doesn't have
any data member at all) nor any user defined constructor/destructor/
assignment operator, it should be a POD. Therefore, if used in a struct
which otherwise is a POD as well, offsetof is defined. But: does
offsetof
count as "usage" of x? (The offset should be known at compile time;
OTOH offsetof is a macro - may it access x?)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/05/13
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

> Given that objects of "empty" classes [snip] still need memory,
> [snip] I got the idea to conserve space by putting them into an
> union with a data member, f.ex:

> class A { union { X x; int data; }; ...  };

> Now my question: Does the standard guarantee that calls to member
> functions of x don't affect the value of data?

No.  However, there is another way to get the same effect.
See http://www.cantrip.org/emptyopt.html .

Cutting to the chase, a template like

    template <class Base, class Member>
    struct BaseOpt : Base {
      Member m;
      BaseOpt(Base const& b, Member const& mem)
        : Base(b), m(mem) { }
    };

can be used in your class A above like this:

  class A { BaseOpt<X,int> data; ... };

Of course this only helps if your compiler implements the
empty-base optimization, but most will eventually, and it
is harmless on compilers that don't, yet.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.org/



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jason Merrill <jason@cygnus.com>
Date: 1998/05/17
Raw View
BTW, why are members required to have nonzero size?  It seems like they
could be handled the same as bases; namely, they must be padded to avoid
overlapping with another subobject of the same type.

Jason


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/05
Raw View
Given that objects of "empty" classes (that is, classes with no
data members, no virtual functions and no virtual or non-empty
base classes) still need memory, and that inheritance from them
is not always what you want, I got the idea to conserve space by
putting them into an union with a data member, f.ex:

struct X
{
  void f();
  int g(int);
  typedef X* pointer;
};

class A
{
  union
  {
    X x;
    int data;
  };
...
};

Now my question: Does the standard guarantee that calls to member
functions of x don't affect the value of data?


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]