在C中,指向结构的指针总是指向其第一个成员吗?

时间:2011-09-05 20:40:51

标签: c

假设我有许多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++;
}

在示例中,您会注意到结构FooBar都以Base成员开头。

而且,在MethodOperatesOnBase中,我将void *参数转换为Base *

我希望将指向Bar的指针和指向Foo的指针传递给此方法,并依赖结构的第一个成员作为Base结构。

这是可接受的,还是有一些(可能是编译器特定的)问题需要注意? (比如某种填充/填充方案会改变结构的第一个成员的位置?)

3 个答案:

答案 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 *?我不认为这是更多的工作,它确实具有类型安全的优势。