By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,959 Members | 1,196 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,959 IT Pros & Developers. It's quick & easy.

where are unions and bitfields particularly used ?

P: n/a
Hi,
In my couple of years of experience, I have never found a single
instance where I needed to use unions and bitfields(though I have used
structures).I was just imagining where would these find
relevance.Though both of these(bitfields and unions) are used where
space is a constraint(so I can assume always in embedded systems,where
memory is particularly less)and we want to save space/memory.

As far as I have read, there is no difference between structs an
unions apart for saving space(that would also imply how members are
accessed in unions compared to in structs).

Can someone just give a couple of examples/scenario's where these have
actually been used or need to be used.

I was of the impression that structures and unions were user defined
data types until I came to this defination of unions from K&R "Union
is a VARIABLE that may hold (at different times) objects of different
types and sizes, while the compiler keeping track of size and
alignment requirements."

So, is an union an user defined data type or a variable.

and why is it that "A union may only be initialized with a value of
the type of its first member" from K&R ??

TIA
rohit
Nov 14 '05 #1
Share this Question
Share on Google+
23 Replies


P: n/a
"rohit" <pr******@yahoo.com> wrote in message
news:93*************************@posting.google.co m...
In my couple of years of experience, I have never found a single
instance where I needed to use unions and bitfields(though I have used
structures). [snip] Can someone just give a couple of examples/scenario's where these have
actually been used or need to be used.
The only time I can recall that I extensively used a union is where I had a
function which would return one of a number of data formats. Specifically,
this was part of a small DNS client library; having performed a query, this
function could be called repeatedly to iterate over the records in the
response, each one of which might be an IP address, a domain name, or
something else. The only direct advantage (as you noted) is saving space.

Bitfields are often used in non-portable code (where they represent some
particular layout of bits). You could use them if you have a number of
flags - but I generally #define the bit values and use a single "flags"
member.

[snip] So, is an union an user defined data type or a variable.
It's both. I read "variable" as a loose term meaning "something capable of
holding different values."
and why is it that "A union may only be initialized with a value of
the type of its first member" from K&R ??


Because there's no provision in the syntax/grammar of the language to
specify which member to initialise - although I think that is no longer the
case with C99.

Alex
Nov 14 '05 #2

P: n/a
"Alex" <me@privacy.net> writes:
"rohit" <pr******@yahoo.com> wrote in message
news:93*************************@posting.google.co m...
So, is an union an user defined data type or a variable.


It's both. I read "variable" as a loose term meaning "something
capable of holding different values."


This ambiguity often arises when a word that should really only be used
as an adjective is used as a noun. The adjective "union" doesn't have
this problem, i.e. "union type" and "union object" are both unambiguous.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #3

P: n/a
rohit wrote:
Hi,
In my couple of years of experience, I have never found a single
instance where I needed to use unions and bitfields(though I have used
structures).I was just imagining where would these find
relevance.Though both of these(bitfields and unions) are used where
space is a constraint(so I can assume always in embedded systems,where
memory is particularly less)and we want to save space/memory.
Bit fields (in a struct) are used to access hardware or provide state
information about the structure.

As far as I have read, there is no difference between structs an
unions apart for saving space(that would also imply how members are
accessed in unions compared to in structs).
There is one big difference between unions and structs: a union will
allocate space for the largest item in the list. Also, compilers are
allowed to add space between fields.

Can someone just give a couple of examples/scenario's where these have
actually been used or need to be used.
Borlands' IDE uses unions for database fields. The have one variable
to define the kind of field and a union for the field categories.

I was of the impression that structures and unions were user defined
data types until I came to this defination of unions from K&R "Union
is a VARIABLE that may hold (at different times) objects of different
types and sizes, while the compiler keeping track of size and
alignment requirements."

So, is an union an user defined data type or a variable.
A union is a stencil showing how data is organized. This stencil is
used for instantiating variables or allocating memory.

and why is it that "A union may only be initialized with a value of
the type of its first member" from K&R ??
Probably to simplify compiler writing. Think about it, how does the
compiler know which data type in the union that the initialized data
is to represent?

TIA
rohit


One word about bitfields: The ordering, most significant bit or
least significant bit, is compiler dependent. Many people who work
on embbed systems or with individual bits, will often use the bit
arithmetic operators on an unsigned integral variable rather than
dealing with bitfields in a structure.
--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Nov 14 '05 #4

P: n/a
On Mon, 10 May 2004, rohit wrote:
Hi,
In my couple of years of experience, I have never found a single
instance where I needed to use unions and bitfields(though I have used
structures).I was just imagining where would these find
relevance.Though both of these(bitfields and unions) are used where
space is a constraint(so I can assume always in embedded systems,where
memory is particularly less)and we want to save space/memory.

As far as I have read, there is no difference between structs an
unions apart for saving space(that would also imply how members are
accessed in unions compared to in structs).

Can someone just give a couple of examples/scenario's where these have
actually been used or need to be used.
Operating systems. The members of a list of resources where unions.
Actually they were structures that contained unions. Soemthing like:

struct device {
int type;
union {
/* a bunch of structures */
/* each structure contains */
/* the necessary information */
/* for one device */
}
}

The code when then use a switch based on the type. If the type was
PRINTER then use the structure within the union that represented a printer
resource. If the type was HARDDRIVE then use the structure within the
union that represented a hard drive resource. Et cetera.
I was of the impression that structures and unions were user defined
data types until I came to this defination of unions from K&R "Union
is a VARIABLE that may hold (at different times) objects of different
types and sizes, while the compiler keeping track of size and
alignment requirements."

So, is an union an user defined data type or a variable.

and why is it that "A union may only be initialized with a value of
the type of its first member" from K&R ??

TIA
rohit


--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to vi************@whitehouse.gov
Nov 14 '05 #5

P: n/a
"rohit" <pr******@yahoo.com> wrote
Can someone just give a couple of examples/scenario's where these have
actually been used or need to be used.


I 've used bitfields for bitmaps of deleted records, when implementing B+ tree
indexes,to save space when storing the index(we 're talking about BIG
indexes), since coincidentialy every block could fit 16 of my records(fixed
size).Of course something like that could be implemented just with bit
operations and masking on 2 chars. Now the only case that I had to use a union
was in flex and bison files.

--
Pascal Adoniou

Nov 14 '05 #6

P: n/a
rohit wrote:

[...]
Can someone just give a couple of examples/scenario's where these have
actually been used or need to be used.


Example of a situation where I've used a union:
I have a bunch of CGI's (C code that generates the content of webpages).
To prevent cluttering that code with HTML constructs (and creating a
maintenance nightmare) I've written a library that does the actual
HTML-generating and exports a more high-level interface to the CGI's.
Some CGI's need to produce form controls so I would like to have an
interface like

lib_add_formctrl(T_formctrl* ctrl, [some general parameters]);

and not

lib_add_textctrl([all the text control parameters]);
lib_add_radioctrl([all the radio control paramters]);
...

T_formctrl is a struct that contains (among some other parameters) a
union and a type indicator (which is a value from an enum):

typedef struct
{
e_formctrl_type type;
union
{
T_textctrl text;
T_radioctrl radio;
...
} u;
} T_formctrl;

where the type of each union member is a struct with the parameters
specific for that type of form control.
To prevent cluttering the CGI's with the code to fill a variable of this
type I've also made some 'factory functions' in the library so you can
create a form control with just one function call:

T_formctrl ctrl;
lib_make_textctrl(&ctrl, [parameters for a text control]);
lib_add_formctrl(&ctrl, [some general parameters]);

Not that special but this also permits me to create other very
convenient high level interface functions. For example the requirements
wanted a table where the cells of a row can contain form controls for
editing or inputting data. Now I can make an interface like

lib_edittable_addrow(int nbCtrls, T_formctrl* ctrl1, ...);

which permits me to output any combination of form control types and any
number of form controls. The library takes care of the drawing details.

In OO terms you might call T_formctrl an abstract base class and
T_textctrl, T_radioctrl, ... the concrete subclasses.

I can't think of another way that can give me this kind of flexibility
with such a concise interface but I'm just a newbie (started my first
job six months ago) still learning every day and this group has readers
with many years of experience :)

--
Dirk

(PGP keyID: 0x448BC5DD - http://www.gnupg.org - http://www.pgp.com)

..oO° Never, ever leapfrog a unicorn. °Oo.
Nov 14 '05 #7

P: n/a
On 10 May 2004 02:10:37 -0700, in comp.lang.c , pr******@yahoo.com (rohit)
wrote:
Hi,
In my couple of years of experience, I have never found a single
instance where I needed to use unions and bitfields


Unions are jolly handy if you have polymorphous data. A commonplace
example is the data in a spreadsheet - it can be text, numbers, formulas,
graphics and so on, all mixed together.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #8

P: n/a
Edd
rohit wrote:
Hi,
In my couple of years of experience, I have never found a single
instance where I needed to use unions and bitfields(though I have used
structures).I was just imagining where would these find
relevance.Though both of these(bitfields and unions) are used where
space is a constraint(so I can assume always in embedded systems,where
memory is particularly less)and we want to save space/memory.

As far as I have read, there is no difference between structs an
unions apart for saving space(that would also imply how members are
accessed in unions compared to in structs).

Can someone just give a couple of examples/scenario's where these have
actually been used or need to be used.

I've used unions similar to this one a few times:

union MyVector
{
struct
{
float x, y, z;
};
float v[3];
};

I can then fill the vector using a loop whose body indexes elements of v, or
if I wish to access or write a particular component I could use somevector.x
rather than somevector.v[0]. The former just seems more intuitive to me.

Another example that I can think of for unions off the top of my head
involves the Quicktime file format. Each atom is described by 4 bytes. So
assuming that on your system sizeof(int)==4, it may be convenient to define
the following union:

union QT_ATOM_TAG
{
char name[4];
int id;
};

In the format description, a 4 letter-code is used to indicate an atom-type,
but for comparisons and so forth, it's probably easier to use the integer
version.
It's a pretty localised example, but there are uses for unions. I've never
really used bit-fields, though.
Edd

Nov 14 '05 #9

P: n/a
> Operating systems. The members of a list of resources where unions.
Actually they were structures that contained unions. Soemthing like:

struct device {
int type;
union {
/* a bunch of structures */
/* each structure contains */
/* the necessary information */
/* for one device */


Is it more common to overlay structures in unions OR having a
structure which has unions as members.Also unions use much less memory
compared to structures(I can understand the situation when if we would
have used a structure of structures instead of a union of structures,
and at a single time only one of the structures is valid like this
example above, we are amounting to memory bloat) as they I suppose do
not have alignment problems and so do not require any padding to be
done.

One more clarification >>
I know that its illegal to take the address of a register variable
using the & operator.But this small example
#include <stdio.h>
int main()
{
register int i=10;
int *ptr;

ptr = &i;
printf("Value of ptr == %d\n",*ptr);
return 0;
}
when compiled
gcc -pedantic -ansi test_register.c -o test -Wall
test_register.c: In function `main':
test_register.c:7: warning: address of register variable `i' requested

../test
Value of ptr == 10

Gives just a warning though I can get the executable.

Also register variables are by default auto variables,I cannot declare
it as an external variable.
This small example proves that :

#include <stdio.h>
register int i=10;
int main()
{
int *ptr;

ptr = &i;
printf("Value of ptr == %d\n",*ptr);
return 0;
}

and compiling it
gcc -pedantic -ansi test_register.c -o test -Wall
test_register.c:2: register name not specified for `i'
test_register.c: In function `main':
test_register.c:7: warning: address of register variable `i' requested

and the binary is not generated.

How am i able to take the value of the regiter variable.I was thinking
of using register storage class for variables of which I wont be
concerned with the address and if I accidently try to acess the
address the compiler should stop me as an error condition.

TIA
rohit
Nov 14 '05 #10

P: n/a
"Edd" <ed***********@nunswithguns.net> writes:
I've used unions similar to this one a few times:

union MyVector
{
struct
{
float x, y, z;
};
float v[3];
};
That's a syntax error: The struct has no name.
I can then fill the vector using a loop whose body indexes elements of
v, or if I wish to access or write a particular component I could use
somevector.x rather than somevector.v[0]. The former just seems more
intuitive to me.


It's undefied behavior to read a union member after setting a different
union member (except for a special case involving two structures with a
common initial sequence of members, which doesn't apply here). So you
cannot set `v[0]' and then read `x'.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #11

P: n/a
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
"Edd" <ed***********@nunswithguns.net> writes:
I've used unions similar to this one a few times:

union MyVector
{
struct
{
float x, y, z;
};
float v[3];
};


That's a syntax error: The struct has no name.
I can then fill the vector using a loop whose body indexes elements of
v, or if I wish to access or write a particular component I could use
somevector.x rather than somevector.v[0]. The former just seems more
intuitive to me.


It's undefied behavior to read a union member after setting a different
union member (except for a special case involving two structures with a
common initial sequence of members, which doesn't apply here). So you
cannot set `v[0]' and then read `x'.


You can, since both have the same type and the same address:

7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:73)

- a type compatible with the effective type of the object,

- a qualified version of a type compatible with the effective
type of the object,

- a type that is the signed or unsigned type corresponding to
the effective type of the object,

- a type that is the signed or unsigned type corresponding to
a qualified version of the effective type of the object,

- an aggregate or union type that includes one of the
aforementioned types among its members (including, recursively,
a member of a subaggregate or contained union), or

- a character type.

____________________

73) The intent of this list is to specify those circumstances
in which an object may or may not be aliased.

A more debatable case is that of using y to access v[1], since a perverse
implementation may insert (unnecessary) padding between x and y, but it
should work on real life implementations.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #12

P: n/a
Da*****@cern.ch (Dan Pop) writes:
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
"Edd" <ed***********@nunswithguns.net> writes:
I've used unions similar to this one a few times:

union MyVector
{
struct
{
float x, y, z;
};
float v[3];
};


That's a syntax error: The struct has no name.
I can then fill the vector using a loop whose body indexes elements of
v, or if I wish to access or write a particular component I could use
somevector.x rather than somevector.v[0]. The former just seems more
intuitive to me.


It's undefied behavior to read a union member after setting a different
union member (except for a special case involving two structures with a
common initial sequence of members, which doesn't apply here). So you
cannot set `v[0]' and then read `x'.


You can, since both have the same type and the same address:

7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:73)

- a type compatible with the effective type of the object,

- a qualified version of a type compatible with the effective
type of the object,

- a type that is the signed or unsigned type corresponding to
the effective type of the object,

- a type that is the signed or unsigned type corresponding to
a qualified version of the effective type of the object,

- an aggregate or union type that includes one of the
aforementioned types among its members (including, recursively,
a member of a subaggregate or contained union), or

- a character type.

____________________

73) The intent of this list is to specify those circumstances
in which an object may or may not be aliased.


You may be right, but I'm not convinced. Why can an implementation not
assume that, after `v[0]' has been written to, `x' has an unspecified
value (in accordance with 6.2.6.1#7), and optimize accordingly (e.g. by
replacing the value of `x' with zero)? I don't see how it follows from
6.5#7 that a conforming implementation cannot do that.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #13

P: n/a
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
"Edd" <ed***********@nunswithguns.net> writes:

I've used unions similar to this one a few times:

union MyVector
{
struct
{
float x, y, z;
};
float v[3];
};

That's a syntax error: The struct has no name.

I can then fill the vector using a loop whose body indexes elements of
v, or if I wish to access or write a particular component I could use
somevector.x rather than somevector.v[0]. The former just seems more
intuitive to me.

It's undefied behavior to read a union member after setting a different
union member (except for a special case involving two structures with a
common initial sequence of members, which doesn't apply here). So you
cannot set `v[0]' and then read `x'.


You can, since both have the same type and the same address:

7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:73)

- a type compatible with the effective type of the object,

- a qualified version of a type compatible with the effective
type of the object,

- a type that is the signed or unsigned type corresponding to
the effective type of the object,

- a type that is the signed or unsigned type corresponding to
a qualified version of the effective type of the object,

- an aggregate or union type that includes one of the
aforementioned types among its members (including, recursively,
a member of a subaggregate or contained union), or

- a character type.

____________________

73) The intent of this list is to specify those circumstances
in which an object may or may not be aliased.


You may be right, but I'm not convinced. Why can an implementation not
assume that, after `v[0]' has been written to, `x' has an unspecified
value (in accordance with 6.2.6.1#7), and optimize accordingly (e.g. by
replacing the value of `x' with zero)? I don't see how it follows from
6.5#7 that a conforming implementation cannot do that.


Reread the footnote. A conforming implementation cannot assume that
aliasing allowed by 6.5#7 doesn't happen. That's why aliasing with an
array of unsigned char is *always* guaranteed to work as expected.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #14

P: n/a
Da*****@cern.ch (Dan Pop) writes:
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:

"Edd" <ed***********@nunswithguns.net> writes:

> I've used unions similar to this one a few times:
>
> union MyVector
> {
> struct
> {
> float x, y, z;
> };
> float v[3];
> };

That's a syntax error: The struct has no name.

> I can then fill the vector using a loop whose body indexes elements of
> v, or if I wish to access or write a particular component I could use
> somevector.x rather than somevector.v[0]. The former just seems more
> intuitive to me.

It's undefied behavior to read a union member after setting a different
union member (except for a special case involving two structures with a
common initial sequence of members, which doesn't apply here). So you
cannot set `v[0]' and then read `x'.

You can, since both have the same type and the same address:

7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:73)

- a type compatible with the effective type of the object,

- a qualified version of a type compatible with the effective
type of the object,

- a type that is the signed or unsigned type corresponding to
the effective type of the object,

- a type that is the signed or unsigned type corresponding to
a qualified version of the effective type of the object,

- an aggregate or union type that includes one of the
aforementioned types among its members (including, recursively,
a member of a subaggregate or contained union), or

- a character type.

____________________

73) The intent of this list is to specify those circumstances
in which an object may or may not be aliased.


You may be right, but I'm not convinced. Why can an implementation not
assume that, after `v[0]' has been written to, `x' has an unspecified
value (in accordance with 6.2.6.1#7), and optimize accordingly (e.g. by
replacing the value of `x' with zero)? I don't see how it follows from
6.5#7 that a conforming implementation cannot do that.


Reread the footnote. A conforming implementation cannot assume that
aliasing allowed by 6.5#7 doesn't happen. That's why aliasing with an
array of unsigned char is *always* guaranteed to work as expected.


Yep, I've been thinking in the wrong direction. Now I am convinced. :)
Thanks.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #15

P: n/a
rohit wrote:
Hi,
In my couple of years of experience, I have never found a single
instance where I needed to use unions and bitfields(though I have
used structures).I was just imagining where would these find
relevance.Though both of these(bitfields and unions) are used
where space is a constraint(so I can assume always in embedded
systems,where memory is particularly less)and we want to save
space/memory. Usually, a union will not save you memory, because you cannot store
different data into its members at the same time.
However, it'll often save a lot of time (see examples below).
As far as I have read, there is no difference between structs an
unions apart for saving space(that would also imply how members
are accessed in unions compared to in structs). See the members of the union as mapped one over the other.

Can someone just give a couple of examples/scenario's where these
have actually been used or need to be used. -----------------
Example: mixed usage of bitfields and unions.
union {
struct {
unsigned sign: 1;
} element;
signed total;
} x;
x.total = 97;
evaluates to:
x.element.sign == 0
y.total = -127;
x.element.sign == 1

Without doing explicit calculations or bit operations, you receive
the desired result. More readable than (x.total and 0x8000).
-----------------
Example:
union {
struct {
unsigned high:8;
unsigned low:8;
} byte;
unsigned wordl;
} x;
x.word = 0x1234;
evaluates to:
x.byte.high=0x12;
x.byte.low=0x34;
and vice versa.
-----------------
Or doing some logarithmic operation on a floating point?
union {
struct {
unsigned sign:1;
signed exponent: 8;
unsigned mantisse:23;
} part;
float value;
} x;
x.value = 1024.0;
x.part.exponent = (x.part.exponent-127)/2+127;
evaluates to
x.value = 32.0; (which is the square root of 1024)
This very fast algorithm reduces square root calculation to exponent
shifting.
However it's not so exact in other cases, thus it's usefulness
depends. I had a situation, where it provided a perfect solution,
anyhow.
Most such code is machine dependent! You cannot rely that this code
will work on all machines identically. That's a usual problem,
however in embedded systems it's often necessary and thus accepted.

I cannot remember that I was able to use unions or bitfields to save
memory.
Very often I gain a performance boost, because I imply logical
decisions or mathematical algorithms into the structure, which
moves the evaluations to compile-time, which saves execution time
and / or code size.
-----------------

I was of the impression that structures and unions were user
defined data types until I came to this defination of unions from
K&R "Union is a VARIABLE that may hold (at different times)
objects of different types and sizes, while the compiler keeping
track of size and alignment requirements."

So, is an union an user defined data type or a variable.
To my opinion, it's a data type. And I did successfully use it this
way for more than a decade.

and why is it that "A union may only be initialized with a value
of the type of its first member" from K&R ??
This shouldn't be a big handicap, because you're free to choose
either member as first. Some compilers don't bother at all...

TIA
rohit


Regards
Bernhard
Nov 14 '05 #16

P: n/a
Martin Dickopp wrote:
"Edd" <ed***********@nunswithguns.net> writes:
I've used unions similar to this one a few times:

union MyVector
{
struct
{
float x, y, z;
};
float v[3];
};


That's a syntax error: The struct has no name.
I can then fill the vector using a loop whose body indexes
elements of v, or if I wish to access or write a particular
component I could use somevector.x rather than somevector.v[0].
The former just seems more intuitive to me.


It's undefied behavior to read a union member after setting a
different union member (except for a special case involving two
structures with a
common initial sequence of members, which doesn't apply here). So
you cannot set `v[0]' and then read `x'.

Martin

I agree fully to your opinion.
However, the OP was asking where unions/bitfields had been used.
I guess that Edd (though with a typo) presented one of the most
common usages of unions.

Since we know, that the standard doesn't provide secure access, whe
should mark such code at least with a highlighted comment in the
source. Nevertheless, it's often convenient and sometimes the only
chance you have, if you want to code really time-critical
applications without escaping into assembly or other ugly things.
(After all, he could do run-time checks to verify that it works on
his machine.)

Though I personally try to stick to the standard as far as possible,
project requirements in the bad $world$ most often demand such
solutions like Edd's. So I implement them.

One embedded system (very small TI microcontroller) with quite a
couple of concurrent threads, which I had to design some years ago,
used it's available memory space time to more than 90%, ran at a
very high load with real-time requirements.
All this was implemented on a self-made operating system which did
most of the resource control like thread-switching with such
union/bitfield structures. It worked smoothly, and without problems
- at production quantities of over 100.000
It was completely programmed in C, which wouldn't had been possible
if I hadn't used comparable "illegal" or "half-legal" accesses.

Bernhard
Nov 14 '05 #17

P: n/a
Martin Dickopp <ex****************@zero-based.org> wrote in message news:<cu*************@zero-based.org>...
Da*****@cern.ch (Dan Pop) writes:
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
Da*****@cern.ch (Dan Pop) writes:

In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:

>"Edd" <ed***********@nunswithguns.net> writes:
>
>> I've used unions similar to this one a few times:
>>
>> union MyVector
>> {
>> struct
>> {
>> float x, y, z;
>> };
>> float v[3];
>> };
>
>That's a syntax error: The struct has no name.
>
>> I can then fill the vector using a loop whose body indexes elements of
>> v, or if I wish to access or write a particular component I could use
>> somevector.x rather than somevector.v[0]. The former just seems more
>> intuitive to me.
>
>It's undefied behavior to read a union member after setting a different
>union member (except for a special case involving two structures with a
>common initial sequence of members, which doesn't apply here). So you
>cannot set `v[0]' and then read `x'.

You can, since both have the same type and the same address:

7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:73)

- a type compatible with the effective type of the object,

- a qualified version of a type compatible with the effective
type of the object,

- a type that is the signed or unsigned type corresponding to
the effective type of the object,

- a type that is the signed or unsigned type corresponding to
a qualified version of the effective type of the object,

- an aggregate or union type that includes one of the
aforementioned types among its members (including, recursively,
a member of a subaggregate or contained union), or

- a character type.

____________________

73) The intent of this list is to specify those circumstances
in which an object may or may not be aliased.

You may be right, but I'm not convinced. Why can an implementation not
assume that, after `v[0]' has been written to, `x' has an unspecified
value (in accordance with 6.2.6.1#7), and optimize accordingly (e.g. by
replacing the value of `x' with zero)? I don't see how it follows from
6.5#7 that a conforming implementation cannot do that.


Reread the footnote. A conforming implementation cannot assume that
aliasing allowed by 6.5#7 doesn't happen. That's why aliasing with an
array of unsigned char is *always* guaranteed to work as expected.


Yep, I've been thinking in the wrong direction. Now I am convinced. :)
Thanks.

Martin

A very good implementation of bit fields would be in Protocol headers
like TCP header had SYN,FIN... , also IP header has the MF,DF bits fir
fragmentation these fields exactly take one bit and there no other way
to handle efficiently them other than bit field.

Also a union is used in places where u want a multiple representaion
of the same entity.
eg: A IP address if of the form 192.168.10.0
u can use it in either ways by declaring a union as
union ip
{
struct byteip
{
int f1:8;
int f2:8;
int f3:8;
int f4:8;
}t1;
struct completeip
{
int f; //considering int to be 32 bits
}t2;
};
This is one use if search many more

Guruz
Nov 14 '05 #18

P: n/a
"Bernhard Holzmayer" <ho****************@deadspam.com> wrote in message
news:13****************@holzmayer.ifr.rt...
Usually, a union will not save you memory, because you cannot store
different data into its members at the same time.


Umm, that's exactly why you /can/ use a union to save memory; there are
situations where the restriction you give doesn't apply. See examples
elsewhere in the thread.

Alex
Nov 14 '05 #19

P: n/a
In <55**************************@posting.google.com > gu**********@yahoo.com (Guruz) writes:
A very good implementation of bit fields would be in Protocol headers
like TCP header had SYN,FIN... , also IP header has the MF,DF bits fir
fragmentation these fields exactly take one bit and there no other way
to handle efficiently them other than bit field.
Unfortunately, there is no way to portably implement an externally
imposed data layout with structures and unions in C. Bit fields are
allocated in an implementation-specific order and padding bytes may be
added anywhere, except at the beginning of a structure.
Also a union is used in places where u want a multiple representaion
of the same entity.
eg: A IP address if of the form 192.168.10.0
u can use it in either ways by declaring a union as
union ip
{
struct byteip
{
int f1:8;
int f2:8;
int f3:8;
int f4:8;
You really want to use unsigned int for all these fields.
}t1;
struct completeip
{
int f; //considering int to be 32 bits
unsigned int works better here, too.
}t2;
};


Question: is f1 mapping the most significant octet of f or the least
significant one? If you can't answer this question (quoting chapter and
verse from the C standard and not the behaviour of your compiler), what's
the use of union ip? ;-)

OTOH, since this approach is quite convenient in practice, all you need
in order to use it on *most* implementations is an alternate definition
of union ip (one in which the order of definition of f1, f2, f3, f4 is
reversed) and an externally defined macro that indicates which definition
must be actually used on that particular implementation. Neither
definition will work on a VAX, but it is highly unlikely that anyone will
bother porting code developed these days to an architecture that has been
dead for a decade...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #20

P: n/a
On Fri, 14 May 2004 15:07:39 +0000, Dan Pop wrote:
[snip discussion on unions and bitfields]
Neither definition will work on a VAX, but it is highly unlikely that
anyone will bother porting code developed these days to an architecture
that has been dead for a decade...


Ah, the VAX: A vast improvement on many of its successors.

(IMHO, writing C for a VAX is a waste of a good ISA anyway. ;) )

--
yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
To email me, rot13 and convert spelled-out numbers to numeric form.
"Makes hackers smile" makes hackers smile.

Nov 14 '05 #21

P: n/a
On 14 May 2004 15:07:39 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <55**************************@posting.google.com > gu**********@yahoo.com (Guruz) writes: <snip>
eg: A IP address [as] a union [of 4 :8 bitfields or one int]

OTOH, since this approach is quite convenient in practice, all you need
in order to use it on *most* implementations is an alternate definition
of union ip (one in which the order of definition of f1, f2, f3, f4 is
reversed) and an externally defined macro that indicates which definition
must be actually used on that particular implementation. Neither
definition will work on a VAX, but it is highly unlikely that anyone will
bother porting code developed these days to an architecture that has been
dead for a decade...

AIR VAX longword (integer) was (pure) little-endian. It was its
floating-point, and I think only some of the several formats, that
followed PDP-11 mixed-endian bogosity, which -11 also did to long.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #22

P: n/a
In <cf********************************@4ax.com> Dave Thompson <da*************@worldnet.att.net> writes:
On 14 May 2004 15:07:39 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <55**************************@posting.google.com > gu**********@yahoo.com (Guruz) writes:

<snip>
>eg: A IP address [as] a union [of 4 :8 bitfields or one int]

OTOH, since this approach is quite convenient in practice, all you need
in order to use it on *most* implementations is an alternate definition
of union ip (one in which the order of definition of f1, f2, f3, f4 is
reversed) and an externally defined macro that indicates which definition
must be actually used on that particular implementation. Neither
definition will work on a VAX, but it is highly unlikely that anyone will
bother porting code developed these days to an architecture that has been
dead for a decade...

AIR VAX longword (integer) was (pure) little-endian. It was its
floating-point, and I think only some of the several formats, that
followed PDP-11 mixed-endian bogosity, which -11 also did to long.


A while ago, when I expressed a similar opinion, P.J. Plauger claimed
that both PDP-11 and the VAX were mixed endian. It made sense, if the
two platforms were supposed to be able to exchange binary data files...

There is no way to define the endianness of floating point types, because
it's far from obvious which is the little end and which is the big one.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #23

P: n/a
On 27 May 2004 12:32:20 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <cf********************************@4ax.com> Dave Thompson <da*************@worldnet.att.net> writes:
On 14 May 2004 15:07:39 GMT, Da*****@cern.ch (Dan Pop) wrote:
[ union 4-byte integer to bytes ] is quite convenient in practice, all you need
in order to use it on *most* implementations is [choice of LE or BE]. Neither
definition will work on a VAX, but [...] that has been
dead for a decade...
AIR VAX longword (integer) was (pure) little-endian. It was its
floating-point, and I think only some of the several formats, that
followed PDP-11 mixed-endian bogosity, which -11 also did to long.


A while ago, when I expressed a similar opinion, P.J. Plauger claimed
that both PDP-11 and the VAX were mixed endian. It made sense, if the
two platforms were supposed to be able to exchange binary data files...

VAX native longs (at machine level and to system calls) were
definitely little-endian -- remember the box drawings aligned on the
right and with (cell) addresses increasing upwards? And you could do
the trick or more likely mistake of passing by reference (e.g.
FORTRAN) a short to a long or vice versa and have it work (only!) for
smallish values. I think there were some programs, and perhaps library
options, that handled (integer) data -- especially, as you say, in
files -- in PDP-11 format, but I didn't use them.
There is no way to define the endianness of floating point types, because
it's far from obvious which is the little end and which is the big one.

The "natural" way, on most machines, was usually to have biased
exponent above "mantissa" (really significand), because before NaNs
(and for normalized values) you could do the same bitwise comparision
(i.e. the same hardware) as for (unsigned) integer and get the correct
result. (And with sign at the top, the same bitwise comparison as S&M
integer, which I think is only a couple of gates different from 2sC.)
And that is in fact how FP11 and (some?) VAX formats are laid out
after you put the bytes in "canonical" order.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #24

This discussion thread is closed

Replies have been disabled for this discussion.