C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Union fun
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
John Max Skaller
Guest





PostPosted: Sun Oct 17, 2004 11:42 pm    Post subject: Union fun Reply with quote



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 ]

Back to top
Ben Hutchings
Guest





PostPosted: Mon Oct 18, 2004 5:35 pm    Post subject: Re: Union fun Reply with quote



"John Max Skaller" wrote:
Quote:
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 ]


Back to top
Jack Klein
Guest





PostPosted: Tue Oct 19, 2004 6:25 am    Post subject: Re: Union fun Reply with quote



On Sun, 17 Oct 2004 23:42:21 GMT, [email]skaller (AT) nospam (DOT) com.au[/email] ("John Max
Skaller") wrote in comp.std.c++:

Quote:
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?

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:

========
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 = { 1 };
u b = a;
u c = 1; // error
u d = { 0, "asdf" }; // error
u e = { "asdf" }; // error
—end 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. ]
========

So I guess g++ isn't wrong.

--
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 ]


Back to top
Richard Smith
Guest





PostPosted: Tue Oct 19, 2004 6:26 am    Post subject: Re: Union fun Reply with quote

John Max Skaller wrote:
Quote:

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 ]


Back to top
John Max Skaller
Guest





PostPosted: Tue Oct 19, 2004 6:28 am    Post subject: Re: Union fun Reply with quote

On Mon, 18 Oct 2004 11:35:01 -0600, Ben Hutchings wrote:

Quote:
"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 ]


Back to top
Ben Hutchings
Guest





PostPosted: Tue Oct 19, 2004 2:47 pm    Post subject: Re: Union fun Reply with quote

"John Max Skaller" wrote:
Quote:
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
Quote:
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 ]


Back to top
Peter Dimov
Guest





PostPosted: Tue Oct 19, 2004 10:59 pm    Post subject: Re: Union fun Reply with quote

[email]skaller (AT) nospam (DOT) com.au[/email] ("John Max Skaller") wrote in message news:<pan.2004.10.19.01.55.50.896756 (AT) nospam (DOT) com.au>...
Quote:
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 aligned_storage<sizeof(T), alignment_of::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 ]


Back to top
Richard Smith
Guest





PostPosted: Wed Oct 20, 2004 12:46 am    Post subject: Re: Union fun Reply with quote

John Max Skaller wrote:
Quote:

"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 ]


Back to top
John Max Skaller
Guest





PostPosted: Wed Oct 20, 2004 2:39 pm    Post subject: Re: Union fun Reply with quote

On Wed, 20 Oct 2004 00:46:51 +0000, Richard Smith wrote:

Quote:
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 ]


Back to top
John Max Skaller
Guest





PostPosted: Thu Oct 21, 2004 1:56 am    Post subject: Re: Union fun Reply with quote

On Tue, 19 Oct 2004 22:59:53 +0000, Peter Dimov wrote:


Quote:
TR1 includes aligned_storage<Len, Align>.

OK, thanks.

You can use
Quote:
aligned_storage<sizeof(T), alignment_of::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 ]


Back to top
John Max Skaller
Guest





PostPosted: Thu Oct 21, 2004 7:08 am    Post subject: Re: Union fun Reply with quote

On Tue, 19 Oct 2004 06:25:32 +0000, Jack Klein wrote:

Quote:
On Sun, 17 Oct 2004 23:42:21 GMT, [email]skaller (AT) nospam (DOT) com.au[/email] ("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 ]


Back to top
Helium
Guest





PostPosted: Mon Oct 25, 2004 6:22 pm    Post subject: Re: Union fun Reply with quote

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


Quote:
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 ]


Back to top
Frank Birbacher
Guest





PostPosted: Tue Oct 26, 2004 10:00 pm    Post subject: Re: Union fun Reply with quote

Hi!

Helium wrote:
Quote:
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 ]


Back to top
John Max Skaller
Guest





PostPosted: Wed Oct 27, 2004 4:33 pm    Post subject: Re: Union fun Reply with quote

On Mon, 25 Oct 2004 18:22:01 +0000, Helium wrote:

Quote:
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.

Quote:
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 ]


Back to top
John Max Skaller
Guest





PostPosted: Wed Oct 27, 2004 6:39 pm    Post subject: Re: Union fun Reply with quote

On Tue, 26 Oct 2004 22:00:51 +0000, Frank Birbacher wrote:

Quote:
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 ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.