B
Bartc
I'm porting some code from a language that allows casual aliases to struct
fields and between variables.
I can duplicate some of this with unions but the results look inelegant. The
first example involves structs:
#include <stdio.h>
typedef struct {
short int a,b; /* assume 16-bit short and 32-bit int in this example
*/
int c,d,e;
} vrec;
int main(void)
{static vrec v;
vrec *p = &v;
p->a = 23;
p->b = 1;
printf("V = %d %d : %d %d %d\n",v.a,v.b, v.c, v.d, v.e);
}
The above is OK, but sometimes I would like to deal with .a and .b fields as
a single 32-bit value. (My compiler should optimise the assignments of 23,1
above but it doesn't). I came up with:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
union {
struct {short int a,b;}s;
int ab;
} u;
int c,d,e;
} vrec;
int main(void)
{static vrec v;
vrec *p = &v;
p->u.ab = 1<<16 | 23;
printf("V = %d %d : %d %d %d\n",v.u.s.a, v.u.s.b, v.c, v.d, v.e);
}
Works, but field access is much more untidy, and I'd prefer to hide the
mechanism I used to combine .a and .b for some operations. Is there a better
way? (Before, I was using something like:
short int a,b;
int ab @ a
I've tried unions to solve my other problem: 2 variables, of different
types, which share the same memory, but run into the same problems of extra
clutter being generated. Is there a simple way in C of achieving:
double x;
int a @ x; /* store a at the same address as x, or: */
char s[10];
short b @ s[2]; /* store b at same address as s[2..3] */
This is possible to achieve using complicated casts; or defining the
equivalenced variable as a macro which contains the cast needed. But both
are fiddly.
fields and between variables.
I can duplicate some of this with unions but the results look inelegant. The
first example involves structs:
#include <stdio.h>
typedef struct {
short int a,b; /* assume 16-bit short and 32-bit int in this example
*/
int c,d,e;
} vrec;
int main(void)
{static vrec v;
vrec *p = &v;
p->a = 23;
p->b = 1;
printf("V = %d %d : %d %d %d\n",v.a,v.b, v.c, v.d, v.e);
}
The above is OK, but sometimes I would like to deal with .a and .b fields as
a single 32-bit value. (My compiler should optimise the assignments of 23,1
above but it doesn't). I came up with:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
union {
struct {short int a,b;}s;
int ab;
} u;
int c,d,e;
} vrec;
int main(void)
{static vrec v;
vrec *p = &v;
p->u.ab = 1<<16 | 23;
printf("V = %d %d : %d %d %d\n",v.u.s.a, v.u.s.b, v.c, v.d, v.e);
}
Works, but field access is much more untidy, and I'd prefer to hide the
mechanism I used to combine .a and .b for some operations. Is there a better
way? (Before, I was using something like:
short int a,b;
int ab @ a
I've tried unions to solve my other problem: 2 variables, of different
types, which share the same memory, but run into the same problems of extra
clutter being generated. Is there a simple way in C of achieving:
double x;
int a @ x; /* store a at the same address as x, or: */
char s[10];
short b @ s[2]; /* store b at same address as s[2..3] */
This is possible to achieve using complicated casts; or defining the
equivalenced variable as a macro which contains the cast needed. But both
are fiddly.