In C, does a pointer to a structure always point t

2020-01-24 03:10发布

Suppose I have a number of C structs for which I would like a particular set of functions to operate upon.

I'm wondering if the following is a legitimate approach:

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++;
}

In the example you'll notice that both structs Foo and Bar begin with a Base member.

And, that in MethodOperatesOnBase, I cast the void * parameter to Base *.

I'd like to pass pointers to Bar and pointers to Foo to this method and rely on the first member of the struct to be a Base struct.

Is this acceptable, or are there some (possibly compiler-specific) issues I need to be aware of? (Such as some sort of packing/padding scheme that would change the location of the first member of a struct?)

标签: c
3条回答
别忘想泡老子
2楼-- · 2020-01-24 03:26

I'm not disagreeing with any of the answers saying that what you suggested will work, but in the interests of a more complete discussion (without suggesting you use C++!), why not do something like

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);

Is there some reason that won't work and you need to use void *? I don't see that this is much more work and it does have the advantage of type-safety.

查看更多
地球回转人心会变
3楼-- · 2020-01-24 03:29

Yes, the C standard specifically guarantees that this will work.

(C1x §6.7.2.1.13: "A pointer to a structure object, suitably converted, points to its initial member ... and vice versa. There may be unnamed padding within as structure object, but not at its beginning.")

查看更多
戒情不戒烟
4楼-- · 2020-01-24 03:48

The whole gtk+ is implemented like that. I cannot think of a better example. Take a look at http://git.gnome.org/browse/gtk+/tree/gtk/

查看更多
登录 后发表回答