Question about incomplete array element types

Discussion in 'C Programming' started by Paul F. Dietz, Jul 11, 2003.

  1. Is the following legal C?

    struct foo;
    struct foo (*p)[10]; /* Pointer to array of 10 foo structures */
    struct foo { int bar; int baz; };
    main() { printf("%d\n", sizeof(*p)); }


    Paul Dietz
    Paul F. Dietz, Jul 11, 2003
    #1
    1. Advertising

  2. Paul F. Dietz

    Chris Torek Guest

    In article <> Paul F. Dietz <> asks:
    >Is the following legal C?
    >
    >struct foo;
    >struct foo (*p)[10]; /* Pointer to array of 10 foo structures */
    >struct foo { int bar; int baz; };
    >main() { printf("%d\n", sizeof(*p)); }


    (You should make it "int main()" and add a "return 0;" statement at
    the end too, of course; and you need to #include <stdio.h>; but I
    assume you have already done this. :) )

    I was going to say "yes"; then I checked the wording in the standard.

    The first line creates the type "struct foo" as an incomplete type.
    The second refers back to it and declares "p" as a pointer to "array
    10 of that incomplete type." This is where the problem appears to
    lie: the Standard says that an array can only have an object type
    as its element type. An incomplete type is not an object type,
    so "array 10 of <incomplete>" is not a valid array type.

    Of course, there seems to be no particular reason to forbid pointers
    to "array N of <incomplete>", especially since C *does* allow
    pointers to incomplete types, including the type "pointer to array
    ? of T" for some object type T:

    typedef some_object_type_here T;
    extern T (*p2)[]; /* valid */

    When the size is missing, as in this case, the array itself is an
    incomplete type, so "p2" is a pointer to an incomplete type.
    (Similarly, "void" is an incomplete type that can never be completed,
    so "void *p3" makes p3 a pointer to an incomplete type.)

    Still, this is what the standard says, however wrongheaded it might
    be, so the second line appears to violate a constraint and require
    a diagnostic. "gcc -ansi -pedantic" seems to agree with me, which
    gives me additional confidence that I have not misinterpreted the
    wording. :)
    --
    In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://67.40.109.61/torek/index.html (for the moment)
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Jul 11, 2003
    #2
    1. Advertising

  3. Paul F. Dietz

    Ravi Uday Guest

    "Paul F. Dietz" <> wrote in message news:<>...
    > Is the following legal C?
    >
    > struct foo;
    > struct foo (*p)[10]; /* Pointer to array of 10 foo structures */
    > struct foo { int bar; int baz; };
    > main() { printf("%d\n", sizeof(*p)); }
    >
    >
    > Paul Dietz
    >


    Yes, except that *main* returns *int* so return - 0 / EXIT_SUCCESS/ EXIT_FAILURE.

    Even better -
    struct foo {
    int bar;
    int baz; };

    struct foo (*p)[10]; /* Pointer to array of 10 foo structures */

    int main() {
    printf("%d\n", sizeof(*p));
    return 0;

    }
    Ravi Uday, Jul 11, 2003
    #3
  4. Paul F. Dietz

    Kevin Easton Guest

    Chris Torek <> wrote:
    > In article <> Paul F. Dietz <> asks:
    >>Is the following legal C?
    >>
    >>struct foo;
    >>struct foo (*p)[10]; /* Pointer to array of 10 foo structures */
    >>struct foo { int bar; int baz; };
    >>main() { printf("%d\n", sizeof(*p)); }

    >
    > (You should make it "int main()" and add a "return 0;" statement at
    > the end too, of course; and you need to #include <stdio.h>; but I
    > assume you have already done this. :) )
    >
    > I was going to say "yes"; then I checked the wording in the standard.
    >
    > The first line creates the type "struct foo" as an incomplete type.
    > The second refers back to it and declares "p" as a pointer to "array
    > 10 of that incomplete type." This is where the problem appears to
    > lie: the Standard says that an array can only have an object type
    > as its element type. An incomplete type is not an object type,
    > so "array 10 of <incomplete>" is not a valid array type.
    >
    > Of course, there seems to be no particular reason to forbid pointers
    > to "array N of <incomplete>", especially since C *does* allow
    > pointers to incomplete types, including the type "pointer to array
    > ? of T" for some object type T:
    >
    > typedef some_object_type_here T;
    > extern T (*p2)[]; /* valid */
    >
    > When the size is missing, as in this case, the array itself is an
    > incomplete type, so "p2" is a pointer to an incomplete type.
    > (Similarly, "void" is an incomplete type that can never be completed,
    > so "void *p3" makes p3 a pointer to an incomplete type.)
    >
    > Still, this is what the standard says, however wrongheaded it might
    > be, so the second line appears to violate a constraint and require
    > a diagnostic. "gcc -ansi -pedantic" seems to agree with me, which
    > gives me additional confidence that I have not misinterpreted the
    > wording. :)


    That must be a newer version of gcc than 2.95.2 - with it, I get some
    quite strange behaviour. The program:

    #include <stdio.h>

    struct foo (*p)[10];
    struct foo { int a; double b; };

    int main()
    {
    printf("%lu\n", (unsigned long) sizeof (*p));

    return 0;
    }

    fails to compile, as you might expect, but the error is on the printf
    line - "sizeof applied to an incomplete type". However, the following
    program:

    #include <stdio.h>

    struct foo (*p)[10];
    struct foo { int a; double b; };
    struct foo a[10];

    int main()
    {
    printf("%lu\n", (unsigned long) sizeof (*p));

    return 0;
    }

    Compiles without any warnings or errors (-Wall -ansi -pedantic), and
    prints "120". It seems that merely "thinking" about the type
    (struct foo [10]) after the type (struct foo) is completed is enough to
    "fix" it. It seems that 2.95.2 is therefore not a conforming compiler.

    - Kevin.
    Kevin Easton, Jul 11, 2003
    #4
  5. Paul F. Dietz

    Zoran Cutura Guest

    Ravi Uday <> wrote:
    > "Paul F. Dietz" <> wrote in message news:<>...
    >> Is the following legal C?
    >>
    >> struct foo;
    >> struct foo (*p)[10]; /* Pointer to array of 10 foo structures */
    >> struct foo { int bar; int baz; };
    >> main() { printf("%d\n", sizeof(*p)); }
    >>
    >>
    >> Paul Dietz
    >>

    >
    > Yes, except that *main* returns *int* so return - 0 / EXIT_SUCCESS/ EXIT_FAILURE.
    >
    > Even better -


    But it changes the meaning of the code and does not include the problem
    me thinks the OP was heading at.

    > struct foo {
    > int bar;
    > int baz; };
    >
    > struct foo (*p)[10]; /* Pointer to array of 10 foo structures */


    Now struct foo isn't incomplete and struct foo [10] is neither.

    The thing is that we can have a pointer to an incomlete type, but can we
    have a pointer to an array of incomplete type and the answer was given
    by Chris Torek in his parallel post.

    >
    > int main() {
    > printf("%d\n", sizeof(*p));
    > return 0;
    >
    > }


    Naturally one would write it like you suggest, but when you are hiding
    the implementation/definition of the struct from for instance the user
    of a library, this is not what you want to do.
    --
    Z ()
    "LISP is worth learning for the profound enlightenment experience
    you will have when you finally get it; that experience will make you
    a better programmer for the rest of your days." -- Eric S. Raymond
    Zoran Cutura, Jul 11, 2003
    #5
  6. Paul F. Dietz

    Dan Pop Guest

    In <belm8o$hte$> Chris Torek <> writes:

    >In article <> Paul F. Dietz <> asks:
    >>Is the following legal C?
    >>
    >>struct foo;
    >>struct foo (*p)[10]; /* Pointer to array of 10 foo structures */
    >>struct foo { int bar; int baz; };
    >>main() { printf("%d\n", sizeof(*p)); }

    >
    >(You should make it "int main()" and add a "return 0;" statement at
    >the end too, of course; and you need to #include <stdio.h>; but I
    >assume you have already done this. :) )
    >
    >I was going to say "yes"; then I checked the wording in the standard.
    >
    >The first line creates the type "struct foo" as an incomplete type.
    >The second refers back to it and declares "p" as a pointer to "array
    >10 of that incomplete type." This is where the problem appears to
    >lie: the Standard says that an array can only have an object type
    >as its element type. An incomplete type is not an object type,
    >so "array 10 of <incomplete>" is not a valid array type.


    Not at that point (and no diagnostic is required, anyway). However:

    22 An array type of unknown size is an incomplete type. It is
    completed, for an identifier of that type, by specifying the
    size in a later declaration (with internal or external linkage).
    A structure or union type of unknown content (as described
    in 6.7.2.3) is an incomplete type. It is completed, for all
    ^^^^^^^
    declarations of that type, by declaring the same structure or
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    union tag with its defining content later in the same scope.

    Since the type is completed by the time sizeof(*p) is evaluated,
    everything should be OK.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jul 11, 2003
    #6
    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:
    354
  2. Mantorok Redgormor

    lvalues -> incomplete types

    Mantorok Redgormor, Feb 6, 2004, in forum: C Programming
    Replies:
    7
    Views:
    413
  3. Replies:
    1
    Views:
    944
    Richard Bos
    Jan 17, 2008
  4. arcadio

    Array has incomplete element type. GCC bug?

    arcadio, Jun 23, 2008, in forum: C Programming
    Replies:
    11
    Views:
    2,153
  5. Timothy Madden
    Replies:
    7
    Views:
    1,089
    Juha Nieminen
    Sep 26, 2010
Loading...

Share This Page