Topic: Trivial default constructors and unions
Author: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1996/08/23 Raw View
In the April 1995 DWP, in the section about unions [class.union],
members of a union are restricted as follows:
... An object of a class with a non-trivial default construc
tor (_class.ctor_), a non-trivial copy constructor (_class.copy_), a
non-trivial destructor (_class.dtor_), or a non-trivial copy assign
ment operator (_over.ass_, _class.copy_) cannot be a member of a
union, nor can array of such objects.
In the secton about constructors [class.ctor], a "trivial" default
constructor is defined as follows:
...
A [default] constructor is trivial if it is an implicitly-declared
default constructor and if:
--its class has no virtual functions (_class.virtual_) and no virtual
base classes (_class.mi_), and
--all the direct base classes of its class have trivial constructors,
and
--for all the nonstatic data members of its class that are of class
type (or array thereof), each such class has a trivial constructor.
Otherwise, the constructor is non-trivial.
This definition of a trivial default constructor leads to problems where
simple classes cannot be used as members of unions, even though the
default constructor doesn't do anything. The problem stems from the
following conflict:
1. Sometimes it is necessary to explicitly declare a default constructor
or else the class will not have a default constructor
2. Such an explicitly declared default constructor cannot, by the above
definition, be trivial.
For example, the following class cannot be used in a union because it
has no default constructor:
class complex
{
double real, imaginary;
public:
complex(double re, double im = 0.0);
// ...
};
If we add a default constructor:
complex() { }
it still cannot be used in a union because the default constructor is
not trivial. Note that this problem *does not* occure for the copy
constructor because *every class* has a copy constructor and it is never
necessary to declare one yourself if the implicitly defined one will
suffice. Similarly, it is not a problem for the destructor.
My proposed solution:
Change the wording of the definition of a trivial default constructor to
something like the following (I tried to make this less verbose, but
failed):
An *empty* constructor is one that is inline, has no
parameters (not even default parameters), no explicit member
initialization list, and no statements or declarations within the
constructor body. An empty constructor for class X would therefore be
defined:
class X
{
X() { }
};
A default constructor is trivial if it is an implicitly-declared
default constructor or a public empty constructor and if:
[ bullet list the same as in existing text (above) ]
What do people think about this problem/solution? It seems like a small
change to me. The only change for the compiler writers is to be able to
recognize an empty constructor (not that it's easy, but it's not as
nearly as hard as something like partial template specialization). Are
there any committee members on line that could sponsor such a change?
Should I make a formal proposal?
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]