copy unnamed union in struct

copy unnamed union in struct

Post by mican » Thu, 10 Jan 2008 21:40:29



Below I've included a C program in which an unnamed union is copied
from one struct to another. Unnamed unions are an extension supported
by many compilers I believe.

The restriction I've posed is that the bit of code that does the
copying cannot assume anything about which member of the union is
active (last set). The code below is ugly because it uses sizeof
applied to a *named* clone (union foo below) of the same anonymous
union (in struct bar below). I am not sure whether those two unions
are guaranteed to have the same size by the C standard. Also it uses
offsetof applied to a member of the unnamed union, and uses the result
in pointer arithmetic to do the copying using memcpy.
Is there a better solution to this problem, and to what extent is this
solution viable?

Stijn


#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>

union foo {
int idx;
void* ptr;
};
struct bar {
double val;
union { int idx; void* ptr; };
};

int main
( int argc
, char* argv[]
)
{ struct bar x, y;
int t;
x.val = 1.43343;
x.ptr = "abde";
y.val = 2.888;
y.ptr = "xyz";

t = offsetof(struct bar, idx);

fprintf(stdout, "x has pointer %p\n", x.ptr);
fprintf(stdout, "y has pointer %p\n", y.ptr);
memcpy(((char*) &y)+t, ((char*) &x)+t, sizeof(union foo));
fprintf(stdout, "y has pointer %p\n", y.ptr);
return 0;
}
 
 
 

copy unnamed union in struct

Post by Ben Bacari » Fri, 11 Jan 2008 07:09:57


XXXX@XXXXX.COM writes:


No, I don't think they are but relying on it will be one of the least
risky things one can do. The fact that you create a maintenance
problem (two versions) is maybe more worrying.


It is probably safe, but why do it? Can't you name the union member
and just use the size of that?

If not, can you add a member after the union? Then you know the
offset to copy up to. Alternately, copy sizeof(struct bar) - t bytes.

<snip>
<snip>

[The above quoted for context.]

--
Ben.

 
 
 

copy unnamed union in struct

Post by Barry Marg » Fri, 11 Jan 2008 07:40:01

In article
< XXXX@XXXXX.COM >,



Unless this extension is specific to Unix C compilers, your question
would probably be better directed to comp.lang.c. They probably have
the best language pedants there.

--
Barry Margolin, XXXX@XXXXX.COM
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
 
 
 

copy unnamed union in struct

Post by Logan Sha » Fri, 11 Jan 2008 14:08:54


I don't really have any idea why you want to spend time playing games
with unions, but one possible solution is to put a named union within
your unnamed union, giving the inner union's members the same name as
the outer union's members. You should then, probably, be able to
access the members with or without the name as you please, and you
should, probably, also be able to access the entire named union
within the outer union. Because the inner union will have all the
same members as the outer union, it should require the same amount
of storage. :-)

Perhaps an example would help:

#define UNION_MEMBERS int idx; void* ptr;

struct bar {
double val;
union {
union { UNION_MEMBERS } myunion;
UNION_MEMBERS;
};
};

struct bar x, y;

Now you should be able to refer to both idx and myunion.idx, both
referring to the same storage (in the same position) and of
the same type.

You should also be able to do this:

struct bar x, y;

y.myunion = x.myunion;

Of course, this is all a gross hack, and I'm not claiming that
any standard anywhere guarantees that this code will do anything.
(But I could imagine it might logically follow from the standard,
somewhat directly, that it might have the behavior that's being
relied upon.)

About the only thing I will claim is that it appears to work on
my system.

- Logan
 
 
 

copy unnamed union in struct

Post by mican » Fri, 11 Jan 2008 18:50:40


They certainly do, they are IMHO also the scariest. I read comp.lang.c
a lot but the place is not inviting, even when considering that
technical discussions are not meant to be a tea party.
 
 
 

copy unnamed union in struct

Post by mican » Fri, 11 Jan 2008 19:13:34


Also in response to Ben Bacarisse elsethread. So far this is a thought
experiment prompted by the following.

I have a sparse matrix library. A matrix entry is represented by a
struct with members <num> idx <value> val, where <num> and <value> are
integer and float types respectively.

For certain applications it would be nice to have, say, a void* ptr
member rather than the <value> member.This could be achieved by
introducing an unnamed union as proposed. An operation such as matrix
transposition would not need to know anything about the unnamed union
(such as which member is active), but it would need to copy it. There
are other ways of course, such as copying the entire struct and then
setting the non-union members.

The unnamed union (hack) would be quite easy to introduce in the
existing codebase (again, this is a thought experiment). This is
admittedly a far cry from a solid ground-up design.


That is quite cunning.
This (ability to refer) is based on assuming rhyme and reason in the
universe, rather than it being garantueed by the C standard? I know
this is a question that may belong to clc, but the wider context of my
question definitely does not fit there.

Thanks,
Stijn
 
 
 

copy unnamed union in struct

Post by Logan Sha » Mon, 14 Jan 2008 09:20:22


Thanks. ;-)


I do not know the C standard very well (especially compared to
the c.l.c folks) and do not know whether it is guaranteed by the
standard or not.

However, it seems quite *possible* it's guaranteed behavior. If
in fact it is, and if you were writing a proof to show that it is
based on other more basic guaranteed behaviors, I think this proof
might involve reasoning that the members of the inner union have
the same relationship to members of the outer union that members
of the outer union have to each other. To wit, there may be
guarantees about the relationship between x and y here:

union {
int x;
int y;
} u;

And those same guarantees might apply to the relationship
between x and y here:

union {
int x;
union {
int y;
} v;
} u;

Again, whether this is true or not, I don't know, but it seems
like the type of thing that, while not intentionally put into
standard explicitly, could implicitly fall out logically from
something else that was put there intentionally.


True, but if you are willing to brave the waters there, you
could narrow your question to something specific about the
guaranteed behavior(s) of unions, and you might be able to
frame the discussion in way that's on-topic and interesting
to the people there *and* get an answer to your question.

That assumes that nested (named) unions are legal, which I'm
fairly sure they are but not 100% sure, and that you phrase
the question in terms of named unions (not unnamed ones),
then extrapolate the named union behavior to the unnamed
unions you're using. (I would think the named vs. unnamed
question would be orthogonal to the nesting question.)

- Logan
 
 
 

copy unnamed union in struct

Post by mican » Tue, 15 Jan 2008 20:05:48

n Jan 13, 12:20 am, Logan Shaw < XXXX@XXXXX.COM > wrote:

I can see the line of reasoning and the proposed orthogonality seems
reasonable. Very recently the following thread washed up from the
rough waters of clc: "how is a struct represented internally", in
which the issue of different struct types with identical members and
member ordering is discussed. The discussion seems to agree with your
line of reasoning.

My default compiler setting is gcc -Wall -pedantic -ansi. I will have
to drop -ansi for this to compile, and -pedantic will generate a
warning, all of which makes perfect sense of course.

This was an interesting excursion, one I may put to use on some
glorious day.

Stijn