Incomplete types

Discussion in 'C Programming' started by John Taylor, Sep 30, 2009.

  1. John Taylor

    John Taylor Guest

    Hello,

    I learned there are object types (describe objects) and function types
    (describe functions). Truly there are also incomplete types, but I can't
    understood what they really are. I read void is an incomplete type. The
    (C99) standard says incomplete types describes objects, too, but "lack
    information needed to determine their sizes". How can you have an object
    without knowing its size? If you have an object, you know its size, just
    by counting the bits required by any of its values. You can answer: "The
    void type comprises an empty set of values": if you have no values, you
    cannot count the number of bits required by any value. The point is that
    in my understanding void should not describe objects at all. An object
    can have a size of zero if the only value it can assume is the empty
    string of bits. But there still is a value in this case. Mathematically,
    the void type seems to be different from the {{}} set. It seems to be
    the empty set ({}). Also, can you name some other incomplete type
    different from void, please?

    Thanks.
    John Taylor, Sep 30, 2009
    #1
    1. Advertising

  2. John Taylor

    John Taylor Guest

    Sorry but your examples looks too complex for me (not your fault
    obviously, my fault). I haven't studied structures and pointers yet.
    John Taylor, Sep 30, 2009
    #2
    1. Advertising

  3. John Taylor

    John Taylor Guest

    pete wrote:
    > /*
    > ** struct inc_1 is an incomplete type.
    > ** arr is of an incomplete type.
    > */
    >
    > /* BEGIN new.c */
    >
    > int main(void)
    > {
    > struct inc_1;
    > extern int arr[];
    > struct inc_1 *p1 = 0;
    >
    > return 0;
    > }
    >
    > /* END new.c */


    I didn't know you can create arrays of unspecified size. How can the
    compiler know how much space to allocate for such an object?
    John Taylor, Sep 30, 2009
    #3
  4. John Taylor

    Avirup Das

    Joined:
    Sep 30, 2009
    Messages:
    1
    /*you'll have to declare array as dynamic memory allocation by using--
    int p;
    p=(int *)malloc(len+1) /*+1 for accomodating \0*/
    --like this*/
    Avirup Das, Sep 30, 2009
    #4
  5. John Taylor

    Willem Guest

    John Taylor wrote:
    ) pete wrote:
    <snip>
    )> extern int arr[];
    )
    ) I didn't know you can create arrays of unspecified size. How can the
    ) compiler know how much space to allocate for such an object?

    The array is not being created there. It's only being declared.
    Basically it's saying "During linking, some other module will define
    an array of int called 'arr' of a size we don't know right now"

    Although I'm not quite sure this is legal; what happens to sizeof(arr) ?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Sep 30, 2009
    #5
  6. John Taylor

    jacob navia Guest

    Richard Heathfield a écrit :
    > In <>, Pietro Cerutti
    > wrote:
    >
    >> On Wed, 30 Sep 2009 12:49:26 +0200, John Taylor wrote:
    >>
    >>> Sorry but your examples looks too complex for me (not your fault
    >>> obviously, my fault). I haven't studied structures and pointers
    >>> yet.

    >>
    >> "Structs and pointers" is where incomplete (aka 'opaque') types come
    >> into play.
    >>
    >> Look at how the FILE type is used by the functions in stdio.h.
    >> You'll see that no function ever accepts or returns an object of
    >> type FILE; instead, pointers to such a type are used. You, as a
    >> programmer, don't know how a FILE object looks like. The exact
    >> representation need only be known to the actual implementation of
    >> the functions in stdio.h, which belong to the standard library.

    >
    > That would be a great example, if only FILE were an incomplete type!
    > :) It is, however, still a /good/ example, since FILE might as well
    > be an incomplete type from a normal portable-C-programmer's
    > perspective. (I specifically exclude /ab/normal
    > portable-C-programmers from that!)
    >


    In the lcc-win 64 bit version FILE *is* an opaque type.
    My stdio.h just does

    struct __FILE;
    typedef struct __FILE FILE;
    extern FILE *_Files[];
    #define stdin (_Files[0])
    #define stdout (_Files[1])
    #define stderr (_Files[2])

    I hope I haven't done something wrong because all the new stdio run time
    seems to work and nowhere is a user visible definition of FILE.
    jacob navia, Sep 30, 2009
    #6
  7. Willem <> writes:

    > John Taylor wrote:
    > ) pete wrote:
    > <snip>
    > )> extern int arr[];
    > )
    > ) I didn't know you can create arrays of unspecified size. How can the
    > ) compiler know how much space to allocate for such an object?
    >
    > The array is not being created there. It's only being declared.
    > Basically it's saying "During linking, some other module will define
    > an array of int called 'arr' of a size we don't know right now"
    >
    > Although I'm not quite sure this is legal; what happens to
    > sizeof(arr) ?


    It's "legal". sizeof arr is not -- it is a constraint violation and
    so must be diagnosed by the implementation.

    --
    Ben.
    Ben Bacarisse, Sep 30, 2009
    #7
  8. John Taylor

    jacob navia Guest

    Richard Heathfield a écrit :
    > In <h9vvpf$vcb$>, jacob navia wrote:
    >
    > <snip>
    >
    >> In the lcc-win 64 bit version FILE *is* an opaque type.

    >
    > That's a conformance issue; it violates 7.19.1(2), which requires that
    > FILE be an object type - i.e. a type that fully describes an object.
    >


    7.19.1(2) says:
    FILE
    which is an object type capable of recording all the information needed to control a
    stream, including its file position indicator, a pointer to its associated buffer (if any), an
    error indicator that records whether a read/write error has occurred, and an end-of-file
    indicator that records whether the end of the file has been reached

    Nowhere do I read that this object type *internals* must be disclosed...

    I have all the required fields in the FILE object, only, you can't access them.
    jacob navia, Sep 30, 2009
    #8
  9. John Taylor

    jacob navia Guest

    Richard Heathfield a écrit :
    > In <ha07kc$a27$>, jacob navia wrote:
    >
    >> Richard Heathfield a écrit :
    >>> In <h9vvpf$vcb$>, jacob navia wrote:
    >>>
    >>> <snip>
    >>>
    >>>> In the lcc-win 64 bit version FILE *is* an opaque type.
    >>> That's a conformance issue; it violates 7.19.1(2), which requires
    >>> that FILE be an object type - i.e. a type that fully describes an
    >>> object.
    >>>

    >> 7.19.1(2) says:
    >> FILE
    >> which is an object type capable of recording all the information
    >> needed to control a stream, including its file position indicator, a
    >> pointer to its associated buffer (if any), an error indicator that
    >> records whether a read/write error has occurred, and an end-of-file
    >> indicator that records whether the end of the file has been reached
    >>
    >> Nowhere do I read that this object type *internals* must be
    >> disclosed...

    >
    > Look up "object type" - it's defined as "type that fully describes the
    > object".
    >
    >> I have all the required fields in the FILE object, only, you can't
    >> access them.

    >
    > In which case the type does not fully describe the object, and
    > therefore FILE is not an object type.
    >


    Well, that was it. I will leave it at that. Non conformant but I can't disclose
    the FILE type since there are many things that can (and will) change. I will
    rewrite that later, when some (paying) customer complains

    :)
    jacob navia, Sep 30, 2009
    #9
  10. John Taylor

    bartc Guest

    "Richard Heathfield" <> wrote in message
    news:...
    > In <ha07kc$a27$>, jacob navia wrote:
    >
    >> Richard Heathfield a écrit :
    >>> In <h9vvpf$vcb$>, jacob navia wrote:


    >>>> In the lcc-win 64 bit version FILE *is* an opaque type.
    >>>
    >>> That's a conformance issue; it violates 7.19.1(2), which requires
    >>> that FILE be an object type - i.e. a type that fully describes an
    >>> object.


    > Look up "object type" - it's defined as "type that fully describes the
    > object".
    >
    >>
    >> I have all the required fields in the FILE object, only, you can't
    >> access them.

    >
    > In which case the type does not fully describe the object, and
    > therefore FILE is not an object type.


    What are the practical consequences of FILE not being an object type?

    --
    bartc
    bartc, Sep 30, 2009
    #10
  11. Richard Heathfield <> writes:

    > That's a conformance issue; it violates 7.19.1(2), which requires that
    > FILE be an object type - i.e. a type that fully describes an object.


    Why does the standard require that? I see no benefit to the
    programmer, and a possible disadvantage to the implementor:
    if one wanted to add more members to the FILE structure,
    it would be handy to know that no user program can depend
    on the old size.
    Kalle Olavi Niemitalo, Sep 30, 2009
    #11
  12. John Taylor

    Phil Carmody Guest

    Ben Bacarisse <> writes:
    > Willem <> writes:
    >
    >> John Taylor wrote:
    >> ) pete wrote:
    >> <snip>
    >> )> extern int arr[];
    >> )
    >> ) I didn't know you can create arrays of unspecified size. How can the
    >> ) compiler know how much space to allocate for such an object?
    >>
    >> The array is not being created there. It's only being declared.
    >> Basically it's saying "During linking, some other module will define
    >> an array of int called 'arr' of a size we don't know right now"
    >>
    >> Although I'm not quite sure this is legal; what happens to
    >> sizeof(arr) ?

    >
    > It's "legal".


    arr is a unary expression that has an incomplete type, so it's a
    contraint violation, surely?

    Phil
    --
    Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
    Phil Carmody, Sep 30, 2009
    #12
  13. jacob navia <> writes:
    > Richard Heathfield a écrit :
    >> In <h9vvpf$vcb$>, jacob navia wrote:
    >>
    >> <snip>
    >>
    >>> In the lcc-win 64 bit version FILE *is* an opaque type.

    >>
    >> That's a conformance issue; it violates 7.19.1(2), which requires
    >> that FILE be an object type - i.e. a type that fully describes an
    >> object.
    >>

    >
    > 7.19.1(2) says:
    > FILE
    > which is an object type capable of recording all the information
    > needed to control a stream, including its file position indicator, a
    > pointer to its associated buffer (if any), an error indicator that
    > records whether a read/write error has occurred, and an end-of-file
    > indicator that records whether the end of the file has been reached
    >
    > Nowhere do I read that this object type *internals* must be disclosed...
    >
    > I have all the required fields in the FILE object, only, you can't
    > access them.


    I believe this program is strictly conforming; if FILE is not an
    object type, it will probably fail to compile:

    #include <stdio.h>
    int main(void)
    {
    sizeof(FILE); /* result is discarded */
    return 0;
    }

    This applies to both C90 and C99.

    The type definition needn't expose any internal details other than the
    size. For example, you could have:

    typedef unsigned char[32] FILE;

    assuming that 32 bytes is enough to hold the required information.
    You could then declare an internal type, say _FILE, and use pointer
    conversion in your library to access the actual information.

    I know of no *practical* drawbacks to making FILE an incomplete type,
    and frankly I think that particular requirement is a bit silly.
    Nevertheless, it is a requirement of the standard, and I believe
    you could meet it without any major changes to your implementation.
    (Getting the size right might be moderately tricky.)

    Whether you consider it worth your time to meet this requirement is,
    as always, entirely up to you.

    Let me be very clear. I am telling you that an implementation with
    FILE as an incomplete type does not fully conform to the C90 or
    C99 standard. My only purpose is to convey this information to you.
    I am not advising you or asking you either to do anything about it
    or not to do anything about it.

    --
    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, Sep 30, 2009
    #13
  14. Phil Carmody <> writes:

    > Ben Bacarisse <> writes:
    >> Willem <> writes:
    >>
    >>> John Taylor wrote:
    >>> ) pete wrote:
    >>> <snip>
    >>> )> extern int arr[];
    >>> )
    >>> ) I didn't know you can create arrays of unspecified size. How can the
    >>> ) compiler know how much space to allocate for such an object?
    >>>
    >>> The array is not being created there. It's only being declared.
    >>> Basically it's saying "During linking, some other module will define
    >>> an array of int called 'arr' of a size we don't know right now"
    >>>
    >>> Although I'm not quite sure this is legal; what happens to
    >>> sizeof(arr) ?

    >>
    >> It's "legal".

    >
    > arr is a unary expression that has an incomplete type, so it's a
    > contraint violation, surely?


    Yes. Why did you snip the part where i said that it was a constraint
    violation (the very next few words, IIRC)?

    I took Willem's "Although I'm not quite sure this is legal" to refer
    to the extern and I was just confirming that is was.

    --
    Ben.
    Ben Bacarisse, Sep 30, 2009
    #14
  15. John Taylor

    Seebs Guest

    On 2009-09-30, Richard Heathfield <> wrote:
    > That's a conformance issue; it violates 7.19.1(2), which requires that
    > FILE be an object type - i.e. a type that fully describes an object.


    Interesting! I was in the past under the impression that it was generally
    accepted that implementors were allowed to do just this. I wonder
    whether that's an intentional change in response to some issue, or just
    a side-effect of some other change.

    -s
    --
    Copyright 2009, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    Seebs, Oct 1, 2009
    #15
  16. John Taylor

    Seebs Guest

    On 2009-09-30, jacob navia <> wrote:
    > Nowhere do I read that this object type *internals* must be disclosed...


    See 6.2.5:

    Types are partitioned into object types (types that fully describe
    objects), function types (types that describe functions), and
    incomplete types (types that describe objects but lack information
    needed to determine their sizes).

    If you can't do sizeof(*stdin), so far as I can tell, you're not providing
    an object type.

    -s
    --
    Copyright 2009, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    Seebs, Oct 1, 2009
    #16
  17. John Taylor

    Flash Gordon Guest

    jacob navia wrote:
    > Richard Heathfield a écrit :
    >> In <ha07kc$a27$>, jacob navia wrote:
    >>
    >>> Richard Heathfield a écrit :
    >>>> In <h9vvpf$vcb$>, jacob navia wrote:
    >>>>
    >>>> <snip>
    >>>>
    >>>>> In the lcc-win 64 bit version FILE *is* an opaque type.
    >>>> That's a conformance issue; it violates 7.19.1(2), which requires
    >>>> that FILE be an object type - i.e. a type that fully describes an
    >>>> object.
    >>>>
    >>> 7.19.1(2) says:
    >>> FILE
    >>> which is an object type capable of recording all the information
    >>> needed to control a stream, including its file position indicator, a
    >>> pointer to its associated buffer (if any), an error indicator that
    >>> records whether a read/write error has occurred, and an end-of-file
    >>> indicator that records whether the end of the file has been reached
    >>>
    >>> Nowhere do I read that this object type *internals* must be
    >>> disclosed...

    >>
    >> Look up "object type" - it's defined as "type that fully describes the
    >> object".
    >>
    >>> I have all the required fields in the FILE object, only, you can't
    >>> access them.

    >>
    >> In which case the type does not fully describe the object, and
    >> therefore FILE is not an object type.

    >
    > Well, that was it. I will leave it at that. Non conformant but I can't
    > disclose
    > the FILE type since there are many things that can (and will) change. I
    > will
    > rewrite that later, when some (paying) customer complains
    >
    > :)


    Entirely your choice.

    Of course, you could do something like...
    typedef unsigned char FILE[__FILESIZE];
    Then, in your implementation of the C library, simply cast it to the
    correct type. This would hide all the details whilst still meeting the
    requirements.

    Of course, one disadvantage to hiding the details is that your getc/putc
    macros cannot as easily take advantage of the freedoms they have, since
    it is rather harder for them to directly access the buffer!
    --
    Flash Gordon
    Flash Gordon, Oct 1, 2009
    #17
  18. John Taylor

    Phil Carmody Guest

    Ben Bacarisse <> writes:
    > Phil Carmody <> writes:
    >
    >> Ben Bacarisse <> writes:
    >>> Willem <> writes:
    >>>
    >>>> John Taylor wrote:
    >>>> ) pete wrote:
    >>>> <snip>
    >>>> )> extern int arr[];
    >>>> )
    >>>> ) I didn't know you can create arrays of unspecified size. How can the
    >>>> ) compiler know how much space to allocate for such an object?
    >>>>
    >>>> The array is not being created there. It's only being declared.
    >>>> Basically it's saying "During linking, some other module will define
    >>>> an array of int called 'arr' of a size we don't know right now"
    >>>>
    >>>> Although I'm not quite sure this is legal; what happens to
    >>>> sizeof(arr) ?
    >>>
    >>> It's "legal".

    >>
    >> arr is a unary expression that has an incomplete type, so it's a
    >> contraint violation, surely?

    >
    > Yes. Why did you snip the part where i said that it was a constraint
    > violation (the very next few words, IIRC)?


    Because meaning should be delivered in a forward direction. Forward
    context should be unnecessary.

    That, and he mentioned "sizeof(arr)", and you later mentioned "sizeof arr".
    Syntactically these are different things.

    Phil
    --
    Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
    Phil Carmody, Oct 1, 2009
    #18
  19. On 1 Oct, 09:11, Phil Carmody <> wrote:

    > Because meaning should be delivered in a forward direction. Forward
    > context should be unnecessary.


    ? communicate normally you polish notation in
    Nick Keighley, Oct 1, 2009
    #19
  20. John Taylor

    James Kuyper Guest

    Richard Heathfield wrote:
    > In <IiPwm.100182$>, bartc wrote:
    >
    > <snip>
    >
    >> What are the practical consequences of FILE not being an object
    >> type?

    >
    > You may or may not consider non-conformance to be a practical problem.


    I think you're addressing the wrong question. I suspect he was asking
    about what the practical consequences would be if the standard removed
    that requirement, so that it would no longer be a conformance issue.

    > The following program is strictly conforming:
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int main(void)
    > {
    > return sizeof(FILE) > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
    > }
    >
    > This program /must/ return EXIT_SUCCESS. But if FILE is an incomplete
    > type, then the program won't even compile. I think that's a big deal.
    > YMMV.


    Considered in terms of a possible relaxation of the standard's
    requirements, I don't think it's a big deal. Because of 7.19.3p6 "The
    address of the FILE object used to control a stream may be significant;
    a copy of a FILE object need not serve in place of the original.".
    Primarily as a result of that clause, there's very little, if anything,
    that you can usefully do with FILE objects that would require knowledge
    of their size.
    James Kuyper, Oct 1, 2009
    #20
    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:
    353
  2. Paul F. Dietz

    Question about incomplete array element types

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

    lvalues -> incomplete types

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

    pointer to incomplete types

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

    extern with incomplete types

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

Share This Page