storing related structs

G

Gray Alien

I have two related structs:


struct A
{
int x ;
void * data ;
};

and

struct B
{
int x, y ;
double z ;
void * data1, *data2 ;
};


These structures (not pointers to them), need to be stored in a another
struct:

struct C
{
unsigned id ;
char name ;

DATA_TYPE the_struct ;
};


Where DATA_TYPE is EITHER a struct A or struct B.

For compatability with existing libraries, I cannot use a void * (for
instance), and cast between struct A and B.


Is there a soln to this problem ?
 
A

Army1987

Gray Alien said:
I have two related structs:


struct A
{
int x ;
void * data ;
};

and

struct B
{
int x, y ;
double z ;
void * data1, *data2 ;
};


These structures (not pointers to them), need to be stored in a another struct:

struct C
{
unsigned id ;
char name ;

DATA_TYPE the_struct ;
};


Where DATA_TYPE is EITHER a struct A or struct B.

For compatability with existing libraries, I cannot use a void * (for instance), and cast between struct A and B.


Is there a soln to this problem ?
struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;
union {
struct A str_A;
struct B str_B;
} the_struct;
};

A union is like a struct, but can only hold an element at a time.
You access members of unions like members of struct. For example,
in the case above to access the double of a struct B in a struct C,
you'll have to use mystructC.the_struct.str_B.z
Or try to find a better way to do what you're trying to do.
 
G

gw7rib

"Gray Alien" <[email protected]> ha scritto nel messaggio

I have two related structs:
struct A
{
int x ;
void * data ;
};

struct B
{
int x, y ;
double z ;
void * data1, *data2 ;
};
These structures (not pointers to them), need to be stored in a another struct:
struct C
{
unsigned id ;
char name ;
DATA_TYPE the_struct ;
};
Where DATA_TYPE is EITHER a struct A or struct B.
For compatability with existing libraries, I cannot use a void * (for instance), and cast between struct A and B.
Is there a soln to this problem ?

struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;
union {
struct A str_A;
struct B str_B;
} the_struct;

};

A union is like a struct, but can only hold an element at a time.
You access members of unions like members of struct. For example,
in the case above to access the double of a struct B in a struct C,
you'll have to use mystructC.the_struct.str_B.z
Or try to find a better way to do what you're trying to do.

To the OP: One way of doing it would be to use a union, as Army1987
has suggested. However, if space isn't an issue, you might do better
including both a struct A and a struct B, and just using the one that
you want. This would seem to have less chance of going horribly wrong,
and might make your code clearer. Is there some reason why this would
not work?

Hope that helps.
Paul.
 
F

Flash Gordon

Gray Alien wrote, On 30/06/07 12:28:
I have two related structs:

struct A


These structures (not pointers to them), need to be stored in a another
struct:

struct C
{
unsigned id ;
char name ;
DATA_TYPE the_struct ;
};


Where DATA_TYPE is EITHER a struct A or struct B.

For compatability with existing libraries, I cannot use a void * (for
instance), and cast between struct A and B.

Is there a soln to this problem ?

Yes, use a union of the two struct types. Obviously you need something
to indicate what is stored so you know how to access it.
 
C

CBFalconer

Gray said:
.... snip ...

These structures (not pointers to them), need to be stored in a
another struct:

struct C
{
unsigned id ;
char name ;

DATA_TYPE the_struct ;
};

Look up the use of 'union'.
 
G

Grey Alien

Army1987 said:
"Grey Alien" <[email protected]> ha scritto nel messaggio
Is there a soln to this problem ?

struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;
union {
struct A str_A;
struct B str_B;
} the_struct;
};

A union is like a struct, but can only hold an element at a time.
You access members of unions like members of struct. For example,
in the case above to access the double of a struct B in a struct C,
you'll have to use mystructC.the_struct.str_B.z
Or try to find a better way to do what you're trying to do.
Thanks - I forgot about unions ! (don't use them that much). Yes this
soln will suffice for what I want to do.
 
G

Grey Alien

Army1987 wrote:

struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;
Why have you declared an enum here? ^ (can't see why this is needed)
 
A

Army1987

Grey Alien said:
Army1987 wrote:

struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;
Why have you declared an enum here? ^ (can't see why this is needed)

The point is, you have to somehow keep track of wheter the union
contains a struct A or a struct B.

 
C

Chris Dollin

Grey Alien wrote:
Army1987 wrote:

struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;
Why have you declared an enum here? ^ (can't see why this is needed)

So you can record whether this union ...
.... is currently supposed to be an A or a B.

As far as solutions go, I think we don't know what problem
you're trying to solve, only the C context you're trying
to solve it in. It may make a difference.
 
F

Flash Gordon

"Gray Alien" <[email protected]> ha scritto nel messaggionews:[email protected]...
Where DATA_TYPE is EITHER a struct A or struct B.
For compatability with existing libraries, I cannot use a void * (for instance), and cast between struct A and B.
Is there a soln to this problem ?
struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;
union {
struct A str_A;
struct B str_B;
} the_struct;

};

A union is like a struct, but can only hold an element at a time.
You access members of unions like members of struct. For example,
in the case above to access the double of a struct B in a struct C,
you'll have to use mystructC.the_struct.str_B.z
Or try to find a better way to do what you're trying to do.

To the OP: One way of doing it would be to use a union, as Army1987
has suggested. However, if space isn't an issue, you might do better
including both a struct A and a struct B, and just using the one that
you want. This would seem to have less chance of going horribly wrong,
and might make your code clearer. Is there some reason why this would
not work?

Hope that helps.

If it is only valid to have one or the other then a union expresses the
intent better and if you are accessing the wrong member something has
already gone horribly wrong.
 
G

Grey Alien

Army1987 said:
Grey Alien said:
Army1987 wrote:

struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;

Why have you declared an enum here? ^ (can't see why this is needed)


The point is, you have to somehow keep track of wheter the union
contains a struct A or a struct B.
Ah, I see. I understand now. Actually it won't be necessary since the
structs themselves contain a 'type' enum
 
C

Chris Dollin

Grey Alien wrote:
Army1987 said:
Army1987 wrote:

<snip></snip>

struct C {
unsigned id;
char name; /* do you mean *name, or name[LARGE_ENOUGH]? */
enum { strA, strB } type;

Why have you declared an enum here? ^ (can't see why this is needed)


The point is, you have to somehow keep track of wheter the union
contains a struct A or a struct B.
Ah, I see. I understand now. Actually it won't be necessary since the
structs themselves contain a 'type' enum

Well, you have to be /careful/, then: you can only reliably get
at that enum (IIRC) if it's either the first field in the structure
(A or B) or a member of that first field.

Safer, I would have said, to have it outside the union -- but
it depends on the /full details of the problem you're trying
to solve/, with which we have not been blessed.
 
G

Grey Alien

Chris Dollin wrote:

Well, you have to be /careful/, then: you can only reliably get
at that enum (IIRC) if it's either the first field in the structure
(A or B) or a member of that first field.

Safer, I would have said, to have it outside the union -- but
it depends on the /full details of the problem you're trying
to solve/, with which we have not been blessed.

I agree. Actually, I decided to err on the side of caution and use the
type enum field in struct C (external to the related structs).
 
M

Martin Ambuhl

Gray said:
I have two related structs:


struct A
{
int x ;
void * data ;
};

and

struct B
{
int x, y ;
double z ;
void * data1, *data2 ;
};


These structures (not pointers to them), need to be stored in a another
struct:

struct C
{
unsigned id ;
char name ;

DATA_TYPE the_struct ;
};


Where DATA_TYPE is EITHER a struct A or struct B.

typedef union {
struct A;
struct B;
} DATA_TYPE;
 
D

David Thompson

...
Well, you have to be /careful/, then: you can only reliably get
at that enum (IIRC) if it's either the first field in the structure
(A or B) or a member of that first field.
Actually it's safe if it is in (or within) a common initial sequence
of fields with compatible types. But in practice first is the easiest
way to satisfy this, and almost always desirable anyway.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top