Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-11-03 14:18:01

On Saturday 03 November 2001 03:27, you wrote:
> Actually, I think that there is a third option which would be the
> best long term solution.
> The fundamental problem is that the standard disallows non-PODs in
> unions, hence the need for creating a POD with the same alignment via
> alignment_traits. The language definition could, though, be easily
> extended to allow class types directly in union definitions (perhaps
> requiring a POD as the first (initialised) member). This would remove
> the need for std::aligment_traits<>::align_t.

Unfortunately, then unions need destructors. Those destructors have to call
the destructor of the currently valid member. To know which member is valid,
the size of a union has to be increased to hold a tag. We have now allocated
the storage required for a discriminated union, but we don't yet have the
syntax for checking which member is valid; so we end up extending the
language further to include that syntax. Now unions in C++ differ in
size/layout from unions in C, and we have a whole host of new C compatibility
problems cropping up.

I'm not convinced it's an easy extension.

> (In fact, I vaguely remember reading somewhere on the web that an
> even more extensive upgrade of unions to allow class types was being
> considered for the next language standard anyway. Does anyone have
> any details on that?)
> Failing that however, I agree that a standard
> alignment_traits<>::align_t and ::value is the best library solution.

I take the opposite view on this. We have unions already, and I think we're
stuck with the current semantics for the foreseeable future. They're not
typesafe and they can't deal with all C++ types, so they don't fit well at
all into a high level programming language. It seems that the logical step is
toward a higher-level construct, such as a descriminated union that would
naturally be able to handle any type and would be type safe. Should it be
implemented as a language feature or as a library component?

As a language feature, it'll most likely have a clean syntax and well-defined
semantics. A new keyword will likely be introduced for the construct, which
will break compatibility with C++98. Adoption will probably again be slow -
we can't even rely on relatively simple features being implemented corrected
(partial specialization) 3 years after we had a standard, so how long would
it be until this discriminated union construct becomes mainstream? When would
it be used, e.g., in a Boost library without workarounds? Languages move
slowly, and each feature impacts the entire language in ways that won't be
known for a long time.

As a library feature, we might have to sacrifice some syntax. Instead of:

variant Expression {
  AddExpression add;
  MulExpression mul;
  Variable var;

we might have:

typedef std::variant< tagged<Add, AddExpression>,
                             tagged<Mul, MulExpression>,
                             tagged<Var, Variable> > Expression;

However, we gain in many other areas. Semantics are still well-defined,
adoption can be very fast (most likely, just replace "namespace boost" with
"namespace std"), and there is no impact on the language.

So back to alignof/alignment_traits/etc. The path of minimal impact would be
to provide alignment_traits with some language support to get the "value" and
"align_t" fields. This can't be done complete in a library, but by placing it
in the context of a library we get language support without new syntax or any
language interactions.

Unions have horrible semantics, but we're stuck with them for C
compatibility. So we extend the notion by introducing a new library component
that fits better with C++ semantics, using the underlying C version (since
we're stuck with it anyway). This isn't a new concept - it's precisely what
the Boost Array and Function libraries do (fix C arrays to have C++-like
semantics and fix (member) function pointers to have C++-like semantics).


Boost list run by bdawes at, gregod at, cpdaniel at, john at