In C, does a pointer to a structure always point to its first member?

Suppose I have several C structures for which I would like to use a specific set of functions.

I am wondering if the legal approach is:

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 this example, you will notice that both the Foo and Bar structures begin with a Base member.

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

I would like to pass pointers to Bar and pointers to Foo to this method and rely on the first member of the structure as a Base structure.

Is this acceptable or are there some (possibly compiler specific) issues that I need to know about? (For example, some kind of packing / filling scheme that will change the location of the first member of the structure?)

+30
c
Sep 05 '11 at 20:40
source share
3 answers

Yes, standard C guarantees that this will work.

(C1x ยง6.7.2.1.13: "A pointer to a structural object appropriately transformed points to its initial member ... and vice versa. There may be an unnamed complement as a structural object, but not at its beginning.")

+35
Sep 05 '11 at 20:50
source share

I disagree with any of the answers, saying that what you proposed will work, but in the interests of a more complete discussion (not suggesting using 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 do not see that this is much more work, and it has the advantage of type safety.

+1
Sep 05 2018-11-11T00:
source share

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

+1
Nov 05 '11 at 2:27
source share



All Articles