By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,112 Members | 1,584 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,112 IT Pros & Developers. It's quick & easy.

Question about incomplete array element types

P: n/a
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
di***@dls.net

Nov 13 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
In article <kZ********************@dls.net> Paul F. Dietz <di***@dls.net> 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 (4039.22'N, 11150.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.
Nov 13 '05 #2

P: n/a
"Paul F. Dietz" <di***@dls.net> wrote in message news:<kZ********************@dls.net>...
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
di***@dls.net


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;

}
Nov 13 '05 #3

P: n/a
Chris Torek <no****@elf.eng.bsdi.com> wrote:
In article <kZ********************@dls.net> Paul F. Dietz <di***@dls.net> 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.
Nov 13 '05 #4

P: n/a
Ravi Uday <ra*****@yahoo.com> wrote:
"Paul F. Dietz" <di***@dls.net> wrote in message news:<kZ********************@dls.net>...
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
di***@dls.net
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 (Zo**********@daimlerchrysler.com)
"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
Nov 13 '05 #5

P: n/a
In <be**********@elf.eng.bsdi.com> Chris Torek <no****@elf.eng.bsdi.com> writes:
In article <kZ********************@dls.net> Paul F. Dietz <di***@dls.net> 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: Da*****@ifh.de
Nov 13 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.