473,383 Members | 1,737 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Question about incomplete array element types

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
5 3707
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 (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.
Nov 13 '05 #2
"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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Andrew Ward | last post by:
Hi All, Considering the following code: struct A; struct B { std::list<A> l; };
66
by: Mantorok Redgormor | last post by:
#include <stdio.h> struct foo { int example; struct bar *ptr; }; int main(void) { struct foo baz; baz.ptr = NULL; /* Undefined behavior? */ return 0;
6
by: Eric Smith | last post by:
Is a structure containing an incomplete array as its last element (per paragraph 2 of section 6.7.2.1 of ISO/IEC 9899:1999 (E)) itself an incomplete type? That appears to be indicated by paragraph...
18
by: Giannis Papadopoulos | last post by:
According to the standard (ISO C99 draft WG14/N1124), void is the incomplete type that cannot be completed and comprises the empty set of values. Since it declares the absense of a value can it be...
8
by: dan.winsor | last post by:
Hi all, I'm trying to write through SOAPpy in python to a Java implemented API. The API for the method I want to use is as follows: boolean added = SoapService.addAttachmentsToIssue(token,...
17
by: =?Utf-8?B?U2hhcm9u?= | last post by:
Hi Gurus, I need to transfer a jagged array of byte by reference to unmanaged function, The unmanaged code should changed the values of the array, and when the unmanaged function returns I need...
17
by: DiAvOl | last post by:
Hello everyone, merry christmas! I have some questions about the following program: arrtest.c ------------ #include <stdio.h> int main(int agc, char *argv) {
17
by: Ben Bacarisse | last post by:
candide <toto@free.frwrites: These two statements are very different. The first one is just wrong and I am pretty sure you did not mean to suggest that. There is no object in C that is the...
10
by: arcadio | last post by:
Hi everyone, I'm currently struggling to compile a large piece of legacy code. GCC 3.3 compiles it without complaining, but GCC 4.2.3 (the default in Debian) refuses it and signals "several...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.