给出c中的两个结构:
typedef struct _X_
{
int virtual_a;
int virtual_b;
void *virstual_c;
int a;
int b;
void *c;
/* More fields to follow */
}X;
typedef struct _Y_
{
int a;
int b;
void *c;
/* Same fields as in X structure */
}Y;
问:这样说是否安全?
void foo_low( Y *y )
{
y->a = 1;
y->b = 2;
}
void foo( X *x )
{
Y *y = (Y *)(&(x->a) )
foo_low( y );
}
是标准C吗?它会适用于所有编译器吗?填充有问题吗?
答案 0 :(得分:2)
不,您的功能foo
无法正常工作,因为a
位置错误。
你的例子显然已经弥补,并且会减少我对你真正试图解决的问题的答案的相关性,但是这个定义确实像我相信你要求的那样:
struct header {
int a;
int b;
void *c;
};
struct shared_fields {
int a;
int b;
void *c;
/* More fields to follow */
};
typedef struct
{
struct header virtuals;
struct shared_fields shared;
} X;
typedef struct
{
struct shared_fields shared;
} Y;
void foo_low(struct shared *ys)
{
ys->a = 1;
ys->b = 2;
}
void foo(X *x)
{
foo_low(&x->shared);
}
但是,这不会执行演员表,因为不需要演员表。如果你真的打算通过一个结构设置数据并通过另一个结构访问它,那么标准C中不允许这样做(尽管Hubert描述的同一结构与不同标签可能有例外)。
我怀疑对您提出的问题的更好解决方案是使用union
,这通常可以用来做您可能想到的事情。但严格来说,如果你有一个联合类型的对象u
而你设置了u.a
,那么在设置u.b
之前访问u.b
的值有未定义的行为。虽然人们通常不担心这一点。
答案 1 :(得分:1)
如果两个结构都具有相同的结构,则可以。 struts中字段的名称不必相同,但它们的类型必须相同。 X中的每个子字段必须与其类型和位置中的Y中的子字段匹配。字段名称可以不同。
答案 2 :(得分:1)
那应该有用。但由于你需要以两种不同的方式访问相同的字段(y-> a和x-> a不同),我会使用union:
typedef struct _Y_
{
int a;
int b;
void *c;
/* Same fields as in X structure */
}Y;
typedef struct _X_
{
int virtual_a;
int virtual_b;
void *virstual_c;
Y y_fields;
}X;
typedef union {
X x;
Y y;
} Z;
现在x.virtual_a和y.a位于相同的内存地址中。
您可以按如下方式重写代码:
void foo_low( Z *z )
{
z->y.a = 1;
z->y.b = 2;
}
void foo( Z *z )
{
Z *w = z;
w->y = z->x.y_fields;
foo_low( w );
}
唯一笨拙的部分是在X中添加Y.