【共用体定义】
百度百科
共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。
【Kernel中的一个实例】
struct dst_entry
{
struct dst_entry *next;
...
}...
struct rtable
{
union{
struct dst_entry dst;
struct rtable *rt_next;
}u;
...
}...
在rtable的共用体u的设计和dst_entry{}的定义是有规则可循的。说白了,dst_dentry的第一个成员是一个指针,而不是一个字符成员,这是依据公用体的性质而定义的。在共用体中,union占用的内存空间是最大成员所占用的空间。不同形式访问共用体,如u.dst和u.rt_next,它是按照内存对变量进行赋值的。可以看内核中的一段代码:
int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
u8 tos, struct net_device *dev){
...
struct rtable * rth;
for (rth=rt_hash_table[hash].chain; rth; rth=rth->u.rt_next) {
if (rth->key.dst == daddr && ...rth->key.tos == tos) {
...
rth->u.dst.lastuse = jiffies;
rth->u.dst.__use++;
skb->dst = (struct dst_entry*)rth;
...
}
}
...
}
在此实例中,共用体中真正有意义的变量是:u.rt_next和u.dst除next的所有变量,他们恰好分享了一个内存大小为dst_entry的union。
【测试】
#include <stdio.h>
#include <stddef.h>
typedef struct{
int x;
int y;
}Point;
typedef struct
{
union{
Point p;
int x;
}u;
int pos;
int per;
}Tt;
int main()
{
Tt em;
Point *dmp;
printf("%d\n",sizeof(Tt)); //16
printf("%d\n",offsetof(Tt,u)); //0
printf("%d\n",offsetof(Tt,u.x)); //0
printf("%d\n",offsetof(Tt,u.p.x)); //0
printf("%d\n",offsetof(Tt,u.p.y)); //4
printf("%d\n",offsetof(Tt,pos)); //8
printf("%d\n",offsetof(Tt,per)); //12
em.u.p.x = 1;
em.u.p.y = 2;
printf("%d %d %d\n",em.u.p.x,em.u.p.y,em.u.x); //1 2 1
dmp = (Point * )(&em);
printf("%d %d\n",dmp->x,dmp->y); //1 2
return 0;
}