incomplete types

Discussion in 'C Programming' started by Mark, Jun 12, 2009.

  1. Mark

    Mark Guest

    I'm wondering if it is OK to declare incomplete type like this:

    /* foo.h */
    #ifndef FOO_H
    #define FOO_H

    typedef struct foo foo_t;

    #endif

    /* foo.c */
    #include "foo.h"

    struct foo {
    int x;
    int y;
    };
    ...

    Or it is necessary to make forward structure declaration, as in:
    /* foo.h */
    struct foo;
    typedef struct foo foo_t;

    while 'foo.c' defines the structure members and the like. What's the big difference with these? They compile perfectly well.

    Thanks in advance.

    --
    Mark
    Mark, Jun 12, 2009
    #1
    1. Advertising

  2. Mark

    Richard Bos Guest

    "Mark" <> wrote:

    > SSdtIHdvbmRlcmluZyBpZiBpdCBpcyBPSyB0byBkZWNsYXJlIGluY29tcGxldGUgdHlwZSBsaWtl
    > IHRoaXM6DQoNCi8qIGZvby5oICovDQojaWZuZGVmIEZPT19IDQojZGVmaW5lIEZPT19IDQoNCnR5


    Ik koop deze plaat niet; er zit een kras op.

    Richard
    Richard Bos, Jun 12, 2009
    #2
    1. Advertising

  3. Mark

    Squeamizh Guest

    On Jun 12, 11:16 am, (Richard Bos) wrote:
    > "Mark" <> wrote:
    > > SSdtIHdvbmRlcmluZyBpZiBpdCBpcyBPSyB0byBkZWNsYXJlIGluY29tcGxldGUgdHlwZSBsaWt l
    > > IHRoaXM6DQoNCi8qIGZvby5oICovDQojaWZuZGVmIEZPT19IDQojZGVmaW5lIEZPT19IDQoNCnR 5

    >
    > Ik koop deze plaat niet; er zit een kras op.
    >
    > Richard


    Richard, piss off. This is beneath even you.
    Squeamizh, Jun 12, 2009
    #3
  4. (Richard Bos) writes:
    > "Mark" <> wrote:
    >
    >> SSdtIHdvbmRlcmluZyBpZiBpdCBpcyBPSyB0byBkZWNsYXJlIGluY29tcGxldGUgdHlwZSBsaWtl
    >> IHRoaXM6DQoNCi8qIGZvby5oICovDQojaWZuZGVmIEZPT19IDQojZGVmaW5lIEZPT19IDQoNCnR5

    >
    > Ik koop deze plaat niet; er zit een kras op.


    "No no, *tobacconist's*!"

    Seriously, Mark's article included the following headers:

    Content-Type: text/plain; charset="koi8-r"
    Content-Transfer-Encoding: base64

    My own newsreader was able to display the content as plain text (and I
    didn't even notice the encoding until you pointed it out).

    Mark, please configure your newsreader so it posts in plain ASCII if
    at all possible. Not all newsreaders are able to read base64-encoded
    text.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 12, 2009
    #4
  5. Mark

    Richard Bos Guest

    Keith Thompson <> wrote:

    > (Richard Bos) writes:
    > > "Mark" <> wrote:
    > >
    > >> SSdtIHdvbmRlcmluZyBpZiBpdCBpcyBPSyB0byBkZWNsYXJlIGluY29tcGxldGUgdHlwZSBsaWtl
    > >> IHRoaXM6DQoNCi8qIGZvby5oICovDQojaWZuZGVmIEZPT19IDQojZGVmaW5lIEZPT19IDQoNCnR5

    > >
    > > Ik koop deze plaat niet; er zit een kras op.

    >
    > "No no, *tobacconist's*!"


    Bingo.

    You'd be surprised at how many people have trouble spotting that.

    Richard
    Richard Bos, Jun 13, 2009
    #5
  6. (Richard Bos) writes:
    > Keith Thompson <> wrote:
    >
    >> (Richard Bos) writes:
    >> > "Mark" <> wrote:
    >> >
    >> >> SSdtIHdvbmRlcmluZyBpZiBpdCBpcyBPSyB0byBkZWNsYXJlIGluY29tcGxldGUgdHlwZSBsaWtl
    >> >> IHRoaXM6DQoNCi8qIGZvby5oICovDQojaWZuZGVmIEZPT19IDQojZGVmaW5lIEZPT19IDQoNCnR5
    >> >
    >> > Ik koop deze plaat niet; er zit een kras op.

    >>
    >> "No no, *tobacconist's*!"

    >
    > Bingo.
    >
    > You'd be surprised at how many people have trouble spotting that.


    I wouldn't be too surprised, given that most people I know (myself
    included) don't speak Dutch, and the Babelfish translation was barely
    recognizable.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 13, 2009
    #6
  7. Mark

    Mark Guest

    "Richard Heathfield" <> wrote in message
    news:...
    >> I'm wondering if it is OK to declare incomplete type like this:
    >>
    >> /* foo.h */
    >> #ifndef FOO_H
    >> #define FOO_H
    >>
    >> typedef struct foo foo_t;
    >>
    >> #endif
    >>
    >> /* foo.c */
    >> #include "foo.h"
    >>
    >> struct foo {
    >> int x;
    >> int y;
    >> };

    >
    > Yes, that's fine. In fact, that's a good way to set up opaque types.


    Thanks for your reply.
    The reason I asked is that I also ran into such declaration of incomplete
    type:

    /* foo.h */
    struct foo;
    typedef struct foo *foo_ptr;

    /* foo.c */
    struct foo {
    /* contents go here */
    };

    So, is it equivalent to what I showed in the original post? If so, then
    what's the use of forward structure declaration (I think this is the right
    name) ?

    --
    Mark
    Mark, Jun 15, 2009
    #7
  8. "Mark" <> writes:

    > "Richard Heathfield" <> wrote in message
    > news:...
    >>> I'm wondering if it is OK to declare incomplete type like this:
    >>>
    >>> /* foo.h */
    >>> #ifndef FOO_H
    >>> #define FOO_H
    >>>
    >>> typedef struct foo foo_t;
    >>>
    >>> #endif
    >>>
    >>> /* foo.c */
    >>> #include "foo.h"
    >>>
    >>> struct foo {
    >>> int x;
    >>> int y;
    >>> };

    >>
    >> Yes, that's fine. In fact, that's a good way to set up opaque types.

    >
    > Thanks for your reply.
    > The reason I asked is that I also ran into such declaration of
    > incomplete type:
    >
    > /* foo.h */
    > struct foo;
    > typedef struct foo *foo_ptr;
    >
    > /* foo.c */
    > struct foo {
    > /* contents go here */
    > };
    >
    > So, is it equivalent to what I showed in the original post?


    In your original (if that is what is quoted) there is no foo_ptr type
    and a typedef to make an alias of a struct type so, no, they are not
    equivalent.

    There is debate over the pros and cons of hiding the "pointerness" of
    a type inside a typedef. In general it is probably a bad idea, but
    when the typedef is defining a pointer to an opaque type to give a
    thing some people think of a "handle", then I would be happy to put the
    pointer there in the typedef. Note that I would not then reveal the
    "pointerness" through the type's name.

    The classic example of this, quite reasonably, takes the other view.
    A FILE is an opaque type in that you are not permitted to know
    anything much about it so you must always define and use pointer to
    FILE objects.

    > If so,
    > then what's the use of forward structure declaration (I think this is
    > the right name) ?


    If you mean the "struct foo;" line just before the typedef, then there
    is no point in it.

    --
    Ben.
    Ben Bacarisse, Jun 15, 2009
    #8
  9. Mark

    Guest

    Mark <> wrote:
    >
    > /* foo.h */
    > struct foo;
    > typedef struct foo *foo_ptr;
    >
    > /* foo.c */
    > struct foo {
    > /* contents go here */
    > };
    >
    > So, is it equivalent to what I showed in the original post? If so, then
    > what's the use of forward structure declaration (I think this is the right
    > name) ?


    It's almost equivalent. The point of the forward declaration is to
    ensure you're talking about a new, incomplete struct type and not some
    previously declared struct type. For example, if a user erroneously
    declared their own struct foo before including your foo.h, the forward
    declaration causes an error. Without it, foo_ptr would simply refer to
    the user's struct foo instead of your struct foo.
    --
    Larry Jones

    I don't like these stories with morals. -- Calvin
    , Jun 15, 2009
    #9
  10. writes:

    > Mark <> wrote:
    >>
    >> /* foo.h */
    >> struct foo;
    >> typedef struct foo *foo_ptr;
    >>
    >> /* foo.c */
    >> struct foo {
    >> /* contents go here */
    >> };
    >>
    >> So, is it equivalent to what I showed in the original post? If so, then
    >> what's the use of forward structure declaration (I think this is the right
    >> name) ?

    >
    > It's almost equivalent. The point of the forward declaration is to
    > ensure you're talking about a new, incomplete struct type and not some
    > previously declared struct type. For example, if a user erroneously
    > declared their own struct foo before including your foo.h, the forward
    > declaration causes an error. Without it, foo_ptr would simply refer to
    > the user's struct foo instead of your struct foo.


    Interesting. I tried various things before I replied to see if the
    lone "struct foo;" had any such effect but I failed to find any (over
    and above that provided by the typedef). This included having a
    complete struct foo type defined first.

    Of course this may simply be a problem with my compiler. It is a
    constraint violation or simply UB? I can't find the relevant part of
    the standard.

    --
    Ben.
    Ben Bacarisse, Jun 15, 2009
    #10
  11. Mark

    Tim Rentsch Guest

    Ben Bacarisse <> writes:

    > "Mark" <> writes:
    >
    > > "Richard Heathfield" <> wrote in message
    > > news:...
    > >>> I'm wondering if it is OK to declare incomplete type like this:
    > >>>
    > >>> /* foo.h */
    > >>> #ifndef FOO_H
    > >>> #define FOO_H
    > >>>
    > >>> typedef struct foo foo_t;
    > >>>
    > >>> #endif
    > >>>
    > >>> /* foo.c */
    > >>> #include "foo.h"
    > >>>
    > >>> struct foo {
    > >>> int x;
    > >>> int y;
    > >>> };
    > >>
    > >> Yes, that's fine. In fact, that's a good way to set up opaque types.

    > >
    > > Thanks for your reply.
    > > The reason I asked is that I also ran into such declaration of
    > > incomplete type:
    > >
    > > /* foo.h */
    > > struct foo;
    > > typedef struct foo *foo_ptr;
    > >
    > > /* foo.c */
    > > struct foo {
    > > /* contents go here */
    > > };
    > >
    > > So, is it equivalent to what I showed in the original post?

    >
    > In your original (if that is what is quoted) there is no foo_ptr type
    > and a typedef to make an alias of a struct type so, no, they are not
    > equivalent.
    >
    > There is debate over the pros and cons of hiding the "pointerness" of
    > a type inside a typedef. In general it is probably a bad idea, but
    > when the typedef is defining a pointer to an opaque type to give a
    > thing some people think of a "handle", then I would be happy to put the
    > pointer there in the typedef. Note that I would not then reveal the
    > "pointerness" through the type's name.
    >
    > The classic example of this, quite reasonably, takes the other view.
    > A FILE is an opaque type in that you are not permitted to know
    > anything much about it so you must always define and use pointer to
    > FILE objects.


    A FILE is an object type; it is not opaque in the same way that
    a (struct foo *) type, with no definition for the members of
    (struct foo), is opaque. The model that is used for FILE
    doesn't provide a very good argument for whether to include
    pointerness in a typedef for (struct foo*).
    Tim Rentsch, Jun 19, 2009
    #11
  12. On Mon, 15 Jun 2009 18:38:18 +0100, Ben Bacarisse
    <> wrote:

    > writes:
    >
    > > Mark <> wrote:
    > >>
    > >> /* foo.h */
    > >> struct foo;
    > >> typedef struct foo *foo_ptr;
    > >>
    > >> /* foo.c */
    > >> struct foo {
    > >> /* contents go here */
    > >> };
    > >>
    > >> So, is it equivalent to what I showed in the original post? If so, then
    > >> what's the use of forward structure declaration (I think this is the right
    > >> name) ?

    > >
    > > It's almost equivalent. The point of the forward declaration is to
    > > ensure you're talking about a new, incomplete struct type and not some
    > > previously declared struct type. For example, if a user erroneously
    > > declared their own struct foo before including your foo.h, the forward
    > > declaration causes an error. Without it, foo_ptr would simply refer to
    > > the user's struct foo instead of your struct foo.

    >
    > Interesting. I tried various things before I replied to see if the
    > lone "struct foo;" had any such effect but I failed to find any (over
    > and above that provided by the typedef). This included having a
    > complete struct foo type defined first.
    >
    > Of course this may simply be a problem with my compiler. It is a
    > constraint violation or simply UB? I can't find the relevant part of
    > the standard.


    I too am skeptical. 6.7.2.3p6 says it declares the tag. p1 constraint
    says the _contents_ cannot be redeclared = defined, but not tags.
    p3 says 'all declarations' of the same tag in the same scope declare
    the same type; that certainly seems to allow more than one, although
    it doesn't specifically say a tag-only after the contents -- the
    examples are all of the more useful case of tag-only before contents.
    6.7p3 constraint says that an identifier [with] no linkage shall not
    be redeclared 'except for tags as specified in 6.7.2.3' which punts
    the problem right back.

    The tag-only form does establish a new type in the shadowing case
    (mentioned but not shown in p11 example):

    struct foo { one_set_of_stuff };

    void bar (void) {
    /* inner scope! */
    struct foo;
    typedef struct foo foo_type;
    /* without the tag-only this would use the outer type */
    ...
    struct foo { other_set_of_stuff };
    ...
    }

    and it is (formally) needed in the silly prototype case:

    struct foo;
    void bar (struct foo) ;
    /* without the tag-only that would be a separate type,
    and the call below formally incorrect */
    ....
    struct foo { stuff } x; ... bar (x); ...

    although that can instead use the typedef:

    typedef struct foo foo_type;
    void bar (foo_type) ;
    ....
    struct foo { stuff } ...

    Note: the typedef name can be the same as the tag name,
    because they're in separate namespaces, and I often do
    make them the same where I use both. But for this example
    the distinction is important so I make it more visible.
    David Thompson, Jul 1, 2009
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    360
  2. Paul F. Dietz

    Question about incomplete array element types

    Paul F. Dietz, Jul 11, 2003, in forum: C Programming
    Replies:
    5
    Views:
    455
    Dan Pop
    Jul 11, 2003
  3. Mantorok Redgormor

    lvalues -> incomplete types

    Mantorok Redgormor, Feb 6, 2004, in forum: C Programming
    Replies:
    7
    Views:
    424
  4. Michael Birkmose

    pointer to incomplete types

    Michael Birkmose, May 14, 2004, in forum: C Programming
    Replies:
    7
    Views:
    721
    Dave Thompson
    May 27, 2004
  5. John Temples

    extern with incomplete types

    John Temples, Nov 18, 2004, in forum: C Programming
    Replies:
    0
    Views:
    350
    John Temples
    Nov 18, 2004
Loading...

Share This Page