假设我有许多C结构,我想要一组特定的函数来操作。
我想知道以下是否合法:
typedef struct Base {
int exampleMember;
// ...
} Base;
typedef struct Foo {
Base base;
// ...
} Foo;
typedef struct Bar {
Base base;
// ...
} Bar;
void MethodOperatesOnBase(void *);
void MethodOperatesOnBase(void * obj)
{
Base * base = obj;
base->exampleMember++;
}
在示例中,您会注意到结构Foo
和Bar
都以Base
成员开头。
而且,在MethodOperatesOnBase
中,我将void *
参数转换为Base *
。
我希望将指向Bar
的指针和指向Foo
的指针传递给此方法,并依赖结构的第一个成员作为Base
结构。
这是可接受的,还是有一些(可能是编译器特定的)问题需要注意? (比如某种填充/填充方案会改变结构的第一个成员的位置?)
答案 0 :(得分:38)
是的,C标准明确保证这将有效。
(C1x§6.7.2.1.13:“指向结构对象的指针,适当转换,指向其初始成员......反之亦然。在结构对象中可能有未命名的填充,但不是在其开头。“)
答案 1 :(得分:2)
整个gtk +都是这样实现的。我想不出一个更好的例子。看看http://git.gnome.org/browse/gtk+/tree/gtk/
答案 2 :(得分:1)
我不同意任何答案,说你的建议会起作用,但为了更完整的讨论(不建议你使用C ++!),为什么不做类似的事情
typedef struct Base ... /* The types defined exactly as before */
typedef struct Foo ...
typedef struct Bar ...
/* The function takes a Base* since that is what it actually works with*/
void MethodOperatesOnBase(Base* pbase)
{
/* Do something... */
}
/* Now call it like this: */
Foo foo;
Bar bar;
MethodOperatesOnBase(&foo.base);
MethodOperatesOnBase(&bar.base);
是否有某些原因不起作用,您需要使用void *
?我不认为这是更多的工作,它确实具有类型安全的优势。