Splitting union members in different struct

P

pozz

As someone probably rememeber, I use a quite old C compiler for an
embedded 16-bit processor with some limitations.
One of these regards the initialization of arbitrary members of union
or struct. For example, I can't do the following:

const struct {
int type;
union {
int x;
double y;
} u;
} mystruct = { TYPE_Y, {.y = 3} };

I was thinking to split a struct like the above in two different
struct and a "parent" struct:

typedef struct {
int type;
int x;
} mystruct_x;
typedef struct {
int type;
double y;
} mystruct_y;
typedef struct {
int type;
} mystruct;

The parent struct contains only the common members (in this case, only
the member type).
With the above definitions, I'd like to write something like:

const mystruct_x sx = { TYPE_X, 10 };
const mystruct_y sy = { TYPE_Y, 5.3 };
const mystruct *s;
...
s = (const mystruct *)&sx;
...
if (s->type == TYPE_X) {
const mystruct_x *sx = (const mystruct_x *)s;
printf("x=%d\n", sx->x);
} else if (s->type == TYPE_Y) {
const mystruct_y *sy = (const mystruct_y *)s;
printf("y=%3.1f\n", sy->y);
}

I'm asking if the cast from (mystruct_x *) to (mystruct *) and the
contrary is correctly interpreted.
 
F

Fred

As someone probably rememeber, I use a quite old C compiler for an
embedded 16-bit processor with some limitations.
One of these regards the initialization of arbitrary members of union
or struct. For example, I can't do the following:

  const struct {
    int type;
    union {
      int x;
      double y;
    } u;
  } mystruct = { TYPE_Y, {.y = 3} };

I was thinking to split a struct like the above in two different
struct and a "parent" struct:

  typedef struct {
    int type;
    int x;
  } mystruct_x;
  typedef struct {
    int type;
    double y;
  } mystruct_y;
  typedef struct {
    int type;
  } mystruct;

The parent struct contains only the common members (in this case, only
the member type).
With the above definitions, I'd like to write something like:

  const mystruct_x sx = { TYPE_X, 10 };
  const mystruct_y sy = { TYPE_Y, 5.3 };
  const mystruct *s;
  ...
  s = (const mystruct *)&sx;
  ...
  if (s->type == TYPE_X) {
    const mystruct_x *sx = (const mystruct_x *)s;
    printf("x=%d\n", sx->x);
  } else if (s->type == TYPE_Y) {
    const mystruct_y *sy = (const mystruct_y *)s;
    printf("y=%3.1f\n", sy->y);
  }

I'm asking if the cast from (mystruct_x *) to (mystruct *) and the
contrary is correctly interpreted.

Copy how the Unix XEvent structures do it:

typedef struct {
int type;
} MyStructAny;

typedef struct {
int type;
int x;
} MyStructInt;

typedef struct {
int type;
double y;
} MyStructDouble;

typedef union myStruct {
int type;
MyStructAny my_any;
MyStructInt my_a;
MyStructDouble my_b;
} MyStruct;

const MyStructInt sx = { TYPE_X, 10 };
const MyStructDouble sy = { TYPE_Y, 5.3 };
const MyStruct *s;
...
s = (const MyStruct *)&sx;
...
if (s->type == TYPE_X) {
const MyStructInt *sx = (const MyStructInt *)s;
printf("x=%d\n", sx->x);
} else if (s->type == TYPE_Y) {
const MyStructDouble *sy = (const MyStructDouble *)s;
printf("y=%3.1f\n", sy->y);
}
 
P

pozz

Copy how the Unix XEvent structures do it:

typedef struct {
   int type;

} MyStructAny;

typedef struct {
   int type;
   int x;

} MyStructInt;

typedef struct {
   int type;
   double y;

} MyStructDouble;

typedef union myStruct {
   int type;
   MyStructAny my_any;
   MyStructInt my_a;
   MyStructDouble my_b;

} MyStruct;

Uh? What is this union where you mix the type and the various struct?
When I want to access just to the type member (because I don't know
the
exact type of the struct), I can use just MyStructAny, can't I?
  const MyStructInt sx = { TYPE_X, 10 };
  const MyStructDouble sy = { TYPE_Y, 5.3 };
  const MyStruct *s;
  ...
  s = (const MyStruct *)&sx;
  ...
  if (s->type == TYPE_X) {
    const MyStructInt *sx = (const MyStructInt *)s;
    printf("x=%d\n", sx->x);
  } else if (s->type == TYPE_Y) {
    const MyStructDouble *sy = (const MyStructDouble *)s;
    printf("y=%3.1f\n", sy->y);
  }

I would have wrote:

const MyStructInt sx = { TYPE_X, 10 };
const MyStructDouble sy = { TYPE_Y, 5.3 };
const MyStructAny *s;
...
s = (const MyStructAny *)&sx;
...
if (s->type == TYPE_X) {
const MyStructInt *sx = (const MyStructInt *)s;
printf("x=%d\n", sx->x);
} else if (s->type == TYPE_Y) {
const MyStructDouble *sy = (const MyStructDouble *)s;
printf("y=%3.1f\n", sy->y);
}

so without using the MyStruct at all.

Anyway I'm reading about XEvent structure of Xlib and I found it is
really a union:

typedef struct {
int type;
unsigned long serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display; /* Display the event was read from */
Window window;
} XAnyEvent;
typedef union _XEvent {
int type; /* must not be changed */
XAnyEvent xany;
XKeyEvent xkey;
XButtonEvent xbutton;
...
} XEvent;

But I can't understand. What is the goal to use union to declare the
"parent" class XEvent? I think XEvent is used just to access the type
or the members in xany. Wouldn't be sufficient to use XAnyEvent as
XEvent?
 

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,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top