Topic: Union fun


Author: bloodymir.crap@gmx.net (Frank Birbacher)
Date: Tue, 2 Nov 2004 05:42:36 GMT
Raw View
Hi!

John Max Skaller wrote:
>  { int x; }
>  { double y; }
>
> where the correct model of the stack is:
>
>  union { int x; double y; };
>
> This saves storage. Even if x and y here were constructible
> types it doesn't matter ..

So you could use boost::variant.

Afterall I don't understand, why you cannot use boost. Even in
generated code.

Frank

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Mon, 8 Nov 2004 15:14:19 GMT
Raw View
On Tue, 02 Nov 2004 05:42:36 +0000, Frank Birbacher wrote:

> So you could use boost::variant.
>
> Afterall I don't understand, why you cannot use boost. Even in
> generated code.

There are several reasons.

First: it creates a dependency on a foreign library.
This can create a version mismatch problem for example.
I downloaded boost, it took four hours or so to compile on my box.
Ok, I have a slow box... :) But I couldn't just build it.
I had to build the build system first ...

Since I'm creating a redistributable product, depending
on boost isn't just my problem -- the dependence is
passed on to my clients.

Second, C++ templates and therefore boost has trouble with
type recursion. I noticed some 'recursive' stuff related
to boost variants but I don't know what using it would
look like in practice ..

Three: boost variants are bounded, there's a maximum
number of variants. The maximum may affect compiler
performance. I'd need a large maximum .. 1000 would
be reasonable.

Four: boost variants seem to have some 'safety' features
that will get in the way of generating clean code.
The client is automatically generated code, it doesn't
need as much help doing the right thing as a human programmer.

Five: there is a compile time cost. Many people have slow
computers with low memory and a popular but not very efficient
C++ compiler. I need to minimise compile times. I preprocessed
boost/variant .. and got a 10000 line output (some is probably
iostreams .. )

Six: my code is garbage collected by an exact collector.
This means I have to know the layout of all objects
under control of the collector ..

Seven: it doesn't provide some of the optimisations
I can do. For example I represent 'trivial variants'
by plain integers, and this optimisation is mandatory
for layout reasons (i.e. it isn't just a matter of
efficiency).

Eight: from a brief look at the specs, it seems
boost variants aren't proper sum types: from the spec:

"Each type specified as a template argument to variant must
be distinct after removal of qualifiers.
Thus, for instance, both variant<int, int>
and variant<int, const int> have undefined behavior."

which is useless to me as it stands. I need proper sums,
so I would still have to make a struct containing a
discriminant and the variant. Also isn't clear I can
get the data out (again, visitor is too high level).

The bottom line is that there is a lot of complex
mechanism here to just do what C unions do.

In fact, the aligned_storage<> stuff in boost is only
a few lines of code and does what I need, so I've
actually used that.

So .. I am using boost, just not variant :)


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 9 Nov 2004 16:41:24 GMT
Raw View
skaller@nospam.com.au ("John Max Skaller") wrote in message news:<pan.2004.10.20.14.16.29.574007@nospam.com.au>...
> On Wed, 20 Oct 2004 00:46:51 +0000, Richard Smith wrote:
>
> > Why don't you use boost::variant,
> > <http://www.boost.org/doc/html/variant.html>?  This allows you to
> > safely use non-POD types in what is effectively a union.
>
> Three possible reasons: correct me if I'm wrong.
>
> (1) It undoubtedly pulls in a heap of boost header files.
> This isn't acceptable. .. WOW .. I just looked, and the
> raw includes go off my screen. Its huge!

I'm not sure why that matters.

> (2) The number of variants is limited.

In your application or in Boost?

> (3) It's a template, which means type recursion doesn't work.
> One of the main uses of variants is to implement recursively
> defined inductive types. (Yeah .. I can see 'recursive_wrapper'
> there ..)

If you see that there's recursive variant support, what's the problem?

> Basically, there's a heap of machinery there of no use
> to me. I'm not writing C++ .. I'm generating it.
>
> Here's my current variant type:
>
> //VARIANTS
> struct _uctor_
> {
>   int variant;
>   void *data;
>   _uctor_() : variant(-1), data(0) {}
>   _uctor_(int i, void *d) : variant(i), data(d) {}
> };
>
> I'm forced to use the tagged pointer implementation
> contrary to the design requirements. I'd love to
> replace that void* with an actual union.

I don't see why violating design requirements is better than using Boost.Variant.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Thu, 21 Oct 2004 07:08:00 GMT
Raw View
On Tue, 19 Oct 2004 06:25:32 +0000, Jack Klein wrote:

> On Sun, 17 Oct 2004 23:42:21 GMT, skaller@nospam.com.au ("John Max
> Skaller") wrote in comp.std.c++:

> You have neglected to provide your basis for concluding that g++ is
> wrong.

It is sometimes the case the Standard contains contradictory
statements, and you have to actually know that
one is intended as a special case .. and you have to actually
know it exists as well, otherwise you can draw the wrong conclusion.

At least part of the problem is the really bad
English word 'is' which sometimes means 'has the property'
and sometimes means 'exactly is'.

Here, I wasn't able to find any appropriate wording,
even though I was looking at a nearby paragraph at
the time :)

FYI my example was based on the belief that all
class members must be initialised in order of
writing, perhaps trivially... but that belief
is wrong, it isn't what the Standard says at all.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bekkah@web.de (Helium)
Date: Mon, 25 Oct 2004 18:22:01 GMT
Raw View
You come from a functional language that supports discriminated
unions, right?


> Basically, there's a heap of machinery there of no use
> to me. I'm not writing C++ .. I'm generating it.
>
> Here's my current variant type:
>
> //VARIANTS
> struct _uctor_
> {
>   int variant;
>   void *data;
>   _uctor_() : variant(-1), data(0) {}
>   _uctor_(int i, void *d) : variant(i), data(d) {}
> };
>
> I'm forced to use the tagged pointer implementation
> contrary to the design requirements. I'd love to
> replace that void* with an actual union.
>
> In some other places, I need just an actual union
> without a variant tag (the program counter is enough).
>
> In both cases, it would work if I just stuck to
> supporting C.

What about something like:

You use a strcut containing a char-array. It's size is that of the
largest object you want to store (-> sizeof()).
Than you create objects using placement new in this array (and you
destroy them manually calleng thir destructor).

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bloodymir.crap@gmx.net (Frank Birbacher)
Date: Tue, 26 Oct 2004 22:00:51 GMT
Raw View
Hi!

Helium wrote:
> What about something like:
>
> You use a strcut containing a char-array. It's size is that of the
> largest object you want to store (-> sizeof()).
> Than you create objects using placement new in this array (and you
> destroy them manually calleng thir destructor).

After some days of debugging you resort to boost::any, which
already does that.

Frank

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Wed, 27 Oct 2004 16:33:42 GMT
Raw View
On Mon, 25 Oct 2004 18:22:01 +0000, Helium wrote:

> You come from a functional language that supports discriminated
> unions, right?

Well, I come from a background like

FORTRAN -> Pascal -> C++ -> C -> Tcl -> Python -> Ocaml

(with various assmeblers thrown in) where my involvement with C++
was fairly intense (WG21 NB member for many years),
and my training is in pure maths.

My intent now is to provide C++ programmers with a new platform
that is both source and binary compatible with C and C++,
but which fixes many of the problems and extends capability
considerably, particularly with functional programming
and microthreading.

The compatibility model is to abandon C syntax,
whilst retaining enough of the flavour of C/C++ that a
competent C++ programmer can easily pick it up.
Source compatibility is then achieved with various
source code embedding techniques.

So the intent is an upgrade path with a number of migration
options -- and in particular ensuring that there is no
need to abandon existing code bases. In fact at present,
to use Felix effectively, you're encouraged to mix-and-match
it with C++ and C.

>> In both cases, it would work if I just stuck to
>> supporting C.
>
> What about something like:
>
> You use a strcut containing a char-array. It's size is that of the
> largest object you want to store (-> sizeof()).
> Than you create objects using placement new in this array (and you
> destroy them manually calleng thir destructor).

That is precisely the idea.. but it doesn't work exactly
as you described it, because that struct containing a char
array might not be correctly aligned.

Using the 'alignof()' traits etc seems to enable a solution
that *does* work .. however it is still messy
for a programmer to read the generated code, which is important.

The correct solution is simply to allow unions of constructible
types to be declared, to generate appropriate constructors etc
where possible, and reject the program where it isn't -- but ONLY
if the need arises. The need doesn't arise from merely declaring
the union, and here C++ fails to follow a philosophy and practice
accepted in many other places in the language.

Note that disrciminated unions/variants, or whatever
have nothing to do with functional programming. It's just that
most FP languages are based on mathematics, which clearly indicates
variants are fundamental building blocks for *any*
well engineered language.

My argument here is that it is bad that they're not a basic
part of C++, but it's intolerable that there's no
way to even emulate them other than by using pointers:
in C, unions might not support safe dispatch on variant
tags .. but C doesn't prevent you doing the right thing
unsafely .. which could be quite safe if the code was generated.


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Wed, 27 Oct 2004 18:39:59 GMT
Raw View
On Tue, 26 Oct 2004 22:00:51 +0000, Frank Birbacher wrote:

>> You use a strcut containing a char-array. It's size is that of the
>> largest object you want to store (-> sizeof()).
>> Than you create objects using placement new in this array (and you
>> destroy them manually calleng thir destructor).
>
> After some days of debugging you resort to boost::any, which
> already does that.

I'm not sure exactly what you mean by that. However, please
note boost mainly serves the need of people having to hand
code solutions.

I have a full scale compiler generating code, so I'm treating
C++ as a compiler target language.

The needs of a target language are different to what you need
for human writing, although not unrelated.

In my opinion -- C++ offers a number os *significant* advantages
as a target language over the traditional choices -- C or assmebler.
These include much stronger type checking, which helps debugging
the compiler, constructors and friends, which help reduce the
amount of work the compiler needs to do by delegating it
to the underlying C++ compiler, virtual functions, which make
it easy to build an execution model which is fairly simple
to maintain and modify .. in general, many of the advantages
C++ give a human coder also apply when generating code.

Unfortunately, code generators are *greatly* hampered by lack
of coherence, orthogonality, generality, etc. When you have
this in a target language you have to add lots of special
cases to the compiler.

The failure of unions to allow constructible types is one
such case. Perhaps this protects the human writer and perhaps
not, but there's no doubt it creates a significant obstacle
to systematic code generation.

The need arises in at least two distinct situations, which
are universal in the sense all code generators have to handle
the problem: implementation of variants and representation
of the stack. The latter occurs when you try to build
a data structure to model the stack for code like:

 { int x; }
 { double y; }

where the correct model of the stack is:

 union { int x; double y; };

This saves storage. Even if x and y here were constructible
types it doesn't matter .. the appropriate store will be initialised
and destroyed as control flows through the code (when the
program counter hits the { and } brackets, more or less  .. :)

Unions aren't the only problem -- the type system is a pain,
the lack of support for recursion in templates makes it much
easier to do all generic instantiation in the compiler,
rather than try to generate templates, pointers to members
are incomplete (you can't add them) etc etc.

Still, the union problem is already out of character with
the rest of C++, the changes required are fairly clear,
and they break nothing. So this obstacle could be fairly
easily fixed .. if anyone bothered to consider the idea
that C++ might be a useful target language seriously.

I personally think that it is important, because C++ is never
going to be very good for human coding. Many people have
adopted a grossly inferior platform -- Java -- just to get
a slighly saner syntax plus garbage collection.

Felix tries to provide an alternative which extends C++,
rather than requiring you abandon it, so it ought to
be worth at least considering the idea that it might
just be useful to C++ programmers to make C++ easier
to use as a target language.

Another example easily fixed: offsetof() macro isn't
allowed for non-POD, yet is necessary because pointers
to members incomplete and so worthless for a code generator.
I happen to use it systematically already .. luckily g++
just gives a warning.


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Sun, 17 Oct 2004 23:42:21 GMT
Raw View
IMHO:

union U1 { float a; int b; U1() : a(1.0), b(1); } x;
x.a  // undefined

union U2 { int b; float a; U1() : a(1.0), b(1); } y;
y.a; // 1.0f, well defined

g++ says his:

initializations for multiple members of `U'

I think g++ is wrong.

Comments?

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Ben Hutchings <ben-public-nospam@decadentplace.org.uk>
Date: Mon, 18 Oct 2004 11:35:01 CST
Raw View
"John Max Skaller" wrote:
> IMHO:
>
> union U1 { float a; int b; U1() : a(1.0), b(1); } x;
> x.a  // undefined
>
> union U2 { int b; float a; U1() : a(1.0), b(1); } y;
> y.a; // 1.0f, well defined
>
> g++ says his:
>
> initializations for multiple members of `U'
>
> I think g++ is wrong.
>
> Comments?

It's right.  The standard says in 12.6.2/3:

   "If a ctor-initializer specifies more than one mem-initializer for
    the same member, for the same base class or for multiple members
    of the same union (including members of anonymous unions), the
    ctor-initializer is ill-formed."

--
Ben Hutchings
When in doubt, use brute force. - Ken Thompson

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jackklein@spamcop.net (Jack Klein)
Date: Tue, 19 Oct 2004 06:25:32 GMT
Raw View
On Sun, 17 Oct 2004 23:42:21 GMT, skaller@nospam.com.au ("John Max
Skaller") wrote in comp.std.c++:

> IMHO:
>=20
> union U1 { float a; int b; U1() : a(1.0), b(1); } x;
> x.a  // undefined
>=20
> union U2 { int b; float a; U1() : a(1.0), b(1); } y;
> y.a; // 1.0f, well defined
>=20
> g++ says his:
>=20
> initializations for multiple members of `U'
>=20
> I think g++ is wrong.
>=20
> Comments?

You have neglected to provide your basis for concluding that g++ is
wrong.

There are two ways to look at this, first logically:

What do you think it means to initialize multiple members of a union?
All members of a union start at the same address and occupy the same
space, or at least overlap the beginning of that space.  When you
assign a value to a member of a union, that member has a valid value,
the values of the other members are indeterminate and accessing them
is undefined.  So what possible meaning could initializing more than
one of them have?

The second way to look at this is to see what the C++ standard says.

8.5.1 Aggregates paragraph 15:

=3D=3D=3D=3D=3D=3D=3D=3D
15 When a union is initialized with a brace-enclosed initializer, the
braces shall only contain an initializer for the first member of the
union. [Example:
    union u { int a; char* b; };
    u a =3D { 1 };
    u b =3D a;
    u c =3D 1; // error
    u d =3D { 0, "asdf" }; // error
    u e =3D { "asdf" }; // error
=97end example] [Note: as described above, the braces around the
initializer for a union member can be omitted if the union is a member
of another aggregate. ]
=3D=3D=3D=3D=3D=3D=3D=3D

So I guess g++ isn't wrong.

--=20
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: richard@ex-parrot.com (Richard Smith)
Date: Tue, 19 Oct 2004 06:26:22 GMT
Raw View
John Max Skaller wrote:
>
> union U1 { float a; int b; U1() : a(1.0), b(1); } x;
> x.a  // undefined
>
> union U2 { int b; float a; U1() : a(1.0), b(1); } y;
> y.a; // 1.0f, well defined
>
> g++ says his:
>
> initializations for multiple members of `U'
>
> I think g++ is wrong.

g++ is correct to issue a diagnostic: both code fragments are
ill-formed.

12.6.2/2 says "if a ctor-initializer specifies more than one
mem-initializer ... for multiple members of the same union ..., the
ctor-initializer is ill-formed".

--
Richard Smith

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Tue, 19 Oct 2004 06:28:46 GMT
Raw View
On Mon, 18 Oct 2004 11:35:01 -0600, Ben Hutchings wrote:

> "John Max Skaller" wrote:

>> union U2 { int b; float a; U1() : a(1.0), b(1); } y;
>> y.a; // 1.0f, well defined

> The standard says in 12.6.2/3:
>
>    "If a ctor-initializer specifies more than one mem-initializer for
>     the same member, for the same base class or for multiple members
>     of the same union (including members of anonymous unions), the
>     ctor-initializer is ill-formed."

Ah, thanks. Pity you can put non-POD types in unions then,
I need to do that.. is there a proposal for a template like

 store_of<T>

which has the alignment and size of T and which can be
used in a union, for all value types T?

If I had one of those, it might do as a poor man's
replacement for unions of arbitrary types, the lack of which is
a fairly serious defect.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Tue, 19 Oct 2004 14:47:10 GMT
Raw View
"John Max Skaller" wrote:
> On Mon, 18 Oct 2004 11:35:01 -0600, Ben Hutchings wrote:
>
>> "John Max Skaller" wrote:
>
>>> union U2 { int b; float a; U1() : a(1.0), b(1); } y;
>>> y.a; // 1.0f, well defined
>
>> The standard says in 12.6.2/3:
>>
>>    "If a ctor-initializer specifies more than one mem-initializer for
>>     the same member, for the same base class or for multiple members
>>     of the same union (including members of anonymous unions), the
>>     ctor-initializer is ill-formed."
>
> Ah, thanks. Pity you can put non-POD types in unions then,
> I need to do that.. is there a proposal for a template like
>
>  store_of<T>
>
> which has the alignment and size of T and which can be
> used in a union, for all value types T?

No, but the Type Traits part of TR1 includes information about the
required alignments (std::tr1::alignment_of<T>).

> If I had one of those, it might do as a poor man's
> replacement for unions of arbitrary types, the lack of which is
> a fairly serious defect.

Boost.Variant <http://www.boost.org/libs/variant/> can do that for
you.

--
Ben Hutchings
The world is coming to an end. Please log off.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pdimov@gmail.com (Peter Dimov)
Date: Tue, 19 Oct 2004 22:59:53 GMT
Raw View
skaller@nospam.com.au ("John Max Skaller") wrote in message news:<pan.2004.10.19.01.55.50.896756@nospam.com.au>...
> Ah, thanks. Pity you can put non-POD types in unions then,
> I need to do that.. is there a proposal for a template like
>
>  store_of<T>
>
> which has the alignment and size of T and which can be
> used in a union, for all value types T?

TR1 includes aligned_storage<Len, Align>. You can use
aligned_storage<sizeof(T), alignment_of<T>::value>::type to obtain a
storage type for T. It can be implemented using Boost's type traits as
follows:

template<size_t L, size_t A> struct aligned_storage
{
   union type
   {
      unsigned char data_[ L ];
      typename boost::type_with_alignment<A>::type align_;
   };
};

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: richard@ex-parrot.com (Richard Smith)
Date: Wed, 20 Oct 2004 00:46:51 GMT
Raw View
John Max Skaller wrote:
> >
> >    "If a ctor-initializer specifies more than one mem-initializer for
> >     the same member, for the same base class or for multiple members
> >     of the same union (including members of anonymous unions), the
> >     ctor-initializer is ill-formed."
>
> Ah, thanks. Pity you can put non-POD types in unions then,
> I need to do that.

Why don't you use boost::variant,
<http://www.boost.org/doc/html/variant.html>?  This allows you to
safely use non-POD types in what is effectively a union.

--
Richard Smith

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Wed, 20 Oct 2004 14:39:23 GMT
Raw View
On Wed, 20 Oct 2004 00:46:51 +0000, Richard Smith wrote:

> Why don't you use boost::variant,
> <http://www.boost.org/doc/html/variant.html>?  This allows you to
> safely use non-POD types in what is effectively a union.

Three possible reasons: correct me if I'm wrong.

(1) It undoubtedly pulls in a heap of boost header files.
This isn't acceptable. .. WOW .. I just looked, and the
raw includes go off my screen. Its huge!

(2) The number of variants is limited.

(3) It's a template, which means type recursion doesn't work.
One of the main uses of variants is to implement recursively
defined inductive types. (Yeah .. I can see 'recursive_wrapper'
there ..)

Basically, there's a heap of machinery there of no use
to me. I'm not writing C++ .. I'm generating it.

Here's my current variant type:

//VARIANTS
struct _uctor_
{
  int variant;
  void *data;
  _uctor_() : variant(-1), data(0) {}
  _uctor_(int i, void *d) : variant(i), data(d) {}
};

I'm forced to use the tagged pointer implementation
contrary to the design requirements. I'd love to
replace that void* with an actual union.

In some other places, I need just an actual union
without a variant tag (the program counter is enough).

In both cases, it would work if I just stuck to
supporting C.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: skaller@nospam.com.au ("John Max Skaller")
Date: Thu, 21 Oct 2004 01:56:12 GMT
Raw View
On Tue, 19 Oct 2004 22:59:53 +0000, Peter Dimov wrote:


> TR1 includes aligned_storage<Len, Align>.

OK, thanks.

 You can use
> aligned_storage<sizeof(T), alignment_of<T>::value>::type to obtain a
> storage type for T. It can be implemented using Boost's type traits as
> follows:
>
> template<size_t L, size_t A> struct aligned_storage
> {
>    union type
>    {
>       unsigned char data_[ L ];
>       typename boost::type_with_alignment<A>::type align_;
>    };
> };

Gak! That boost stuff is pretty tricky :)

OK, I think that might work. Thanks.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]