A few questions about a few includes
Am I just completely stupid, or do we have a few things that could use a little cleaning up in /usr/include as well as in the man page for kvm_*? System: FreeBSD 4.5-STABLE 1) The man page for the kvm_* functions lists the following #include dependencies: #include #include #include However, kvm.h contains some declarations that also require and (namely, struct kinfo_proc and struct proc). Otherwise, one might encounter warnings/errors re: incomplete types. 2) If compiling with the -pedantic switch, one might see something like this: In file included from main.c:151: /usr/include/sys/proc.h:108: warning: ANSI C forbids zero-size array `ar_args' In : /* * pargs, used to hold a copy of the command line, if it had a sane * length */ struct pargs { u_int ar_ref; /* Reference count */ u_int ar_length; /* Length */ u_char ar_args[0]; /* Arguments */ }; This does indeed seem to make little or no sense. Could someone explain this? Is ar_args supposed to be a pointer or what? 3) Furthermore, on including , one then sees this: In file included from /usr/include/sys/user.h:40, from main.c:153: /usr/include/machine/pcb.h:90: warning: struct has no members In : /* * The pcb is augmented with machine-dependent additional data for * core dumps. For the i386: ??? */ struct md_coredump { }; Nowhere under /usr/include is a more complete definition of md_coredump to be found. This looks awfully "kludgy" to me. I do hope someone can shed some light here. Thanks. -- Conrad Sabatier <[EMAIL PROTECTED]> First Rule of History: History doesn't repeat itself -- historians merely repeat each other. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
> > In : > > /* > * pargs, used to hold a copy of the command line, if it had a sane > * length > */ > struct pargs { > u_int ar_ref; /* Reference count */ > u_int ar_length; /* Length */ > u_char ar_args[0]; /* Arguments */ > }; > > This does indeed seem to make little or no sense. Could someone explain > this? Is ar_args supposed to be a pointer or what? This is a common technique for defining a structure which is some descriptive information about an array of objects is followed by an open-ended array of those objects. (In this case the "objects" are characters.) The ar_args member of the structure gives a name to that location in the structure without reserving any space (and thus when the technique is used, there can only ever be one [0] member and it must be at the end of the structure). You access the open-ended array of objects just as you would any other array embedded within a structure, E.G. instance->ar_args[n]. Not all compilers support defining zero-length arrays like this. And that's a pity; it's an incredibly useful technique, and the alternatives to it are not nearly as elegant and generally involve ugly recasting of pointers. -- Ian To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
On Sun, Mar 03, 2002 at 10:27:17AM -0700, Ian wrote: > > > > In : > > > > /* > > * pargs, used to hold a copy of the command line, if it had a sane > > * length > > */ > > struct pargs { > > u_int ar_ref; /* Reference count */ > > u_int ar_length; /* Length */ > > u_char ar_args[0]; /* Arguments */ > > }; > > > > This does indeed seem to make little or no sense. Could someone explain > > this? Is ar_args supposed to be a pointer or what? > > This is a common technique for defining a structure which is some > descriptive information about an array of objects is followed by an > open-ended array of those objects. (In this case the "objects" are > characters.) The ar_args member of the structure gives a name to that > location in the structure without reserving any space (and thus when the > technique is used, there can only ever be one [0] member and it must be at > the end of the structure). You access the open-ended array of objects just > as you would any other array embedded within a structure, E.G. > instance->ar_args[n]. > > Not all compilers support defining zero-length arrays like this. And that's > a pity; it's an incredibly useful technique, and the alternatives to it are > not nearly as elegant and generally involve ugly recasting of pointers. For those compilers that don't support zero-length arrays one can still use the same trick but with a one-element array at the end of the struct. One just has to remember to that element into account when allocating memory for the structure. Slightly uglier, but not much. It might be worth mentioning that this trick is not actually allowed according to the C standard and in principle invokes undefined behaviour. OTOH, AFAIK the trick does work on all existing compilers, so while it is not standard-conforming it is quite portable. -- Erik Trulsson [EMAIL PROTECTED] To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
On Sunday 03 March 2002 10:19 am, Conrad Sabatier wrote: > Am I just completely stupid, or do we have a few things that could use a > little cleaning up in /usr/include as well as in the man page for kvm_*? > > System: FreeBSD 4.5-STABLE > > 2) If compiling with the -pedantic switch, one might see something like >this: > > In file included from main.c:151: > /usr/include/sys/proc.h:108: warning: ANSI C forbids zero-size array > `ar_args' > > In : > > /* > * pargs, used to hold a copy of the command line, if it had a sane > * length > */ > struct pargs { > u_int ar_ref; /* Reference count */ > u_int ar_length; /* Length */ > u_char ar_args[0]; /* Arguments */ > }; > > This does indeed seem to make little or no sense. Could someone explain > this? Is ar_args supposed to be a pointer or what? I can explain this one; it's a moderately-common C programming technique. This strucuture will be allocated dynamically. I could be declared like struct pargs { ... u_char *ar_args; } and allocated like pargs = malloc(sizeof(struct pargs)); pargs->ar_args = malloc(args_size); but it's a lot more efficient to declare it as above and allocate it as pargs = malloc(sizeof(struct pargs) + args_+size); since pointers & arrays are equivalent, except that array data is at the location of the name rather than having a pointer to the data at that location, a [0] array has exactly the right semantics for this. You can declare a [1] array for this to make ANSI happy, but then you have to subtract in the allocation and besides that the [0] is "self-documenting" for those who are familir with the technique--after all, there isn't anything *else* you can do with a [0]-sized array. > 3) Furthermore, on including , one then sees this: > > In file included from /usr/include/sys/user.h:40, > from main.c:153: > /usr/include/machine/pcb.h:90: warning: struct has no members > > In : > > /* > * The pcb is augmented with machine-dependent additional data for > * core dumps. For the i386: ??? > */ > struct md_coredump { > }; > > Nowhere under /usr/include is a more complete definition of md_coredump to > be found. This looks awfully "kludgy" to me. A little guesswork here, but this seems pretty self-explanatory to me, too. The md_coredump{} is a structure that includes the *extra* information (beyond what's already in the portable structure) for coredumps on a given architecture. In the case of the 386, there is no useful extra information, so the structure is empty, but since there's a structure someplace that has an instance of struct md_coredump, it must be declared. Since there's no useful content, it is declared as being empty. Seems pretty elegant to me. If I'm off-base here, somebody please jump in! > > I do hope someone can shed some light here. Thanks. [Your point #1 seems valid to me, though.] -- Brian T. Schellenberger . . . . . . . [EMAIL PROTECTED] (work) Brian, the man from Babble-On . . . . [EMAIL PROTECTED] (personal) ME --> http://www.babbleon.org http://www.eff.org <-- GOOD GUYS --> http://www.programming-freedom.org To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
On Sunday 03 March 2002 01:00 pm, Erik Trulsson wrote: > On Sun, Mar 03, 2002 at 10:27:17AM -0700, Ian wrote: > > > In : > > > > > > /* > > > * pargs, used to hold a copy of the command line, if it had a sane > > > * length > > > */ > > > struct pargs { > > > u_int ar_ref; /* Reference count */ > > > u_int ar_length; /* Length */ > > > u_char ar_args[0]; /* Arguments */ > > > }; > > It might be worth mentioning that this trick is not actually allowed > according to the C standard and in principle invokes undefined > behaviour. OTOH, AFAIK the trick does work on all existing compilers, > so while it is not standard-conforming it is quite portable. I can't even imagine how one *would* write a compiler where this would fail--does anybody know the putative risk that led ANSI to "ban" this (IMHO) perfectly-reasonable bahvior? -- Brian T. Schellenberger . . . . . . . [EMAIL PROTECTED] (work) Brian, the man from Babble-On . . . . [EMAIL PROTECTED] (personal) ME --> http://www.babbleon.org http://www.eff.org <-- GOOD GUYS --> http://www.programming-freedom.org To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
"Brian T.Schellenberger" wrote: > I can't even imagine how one *would* write a compiler where this would > fail--does anybody know the putative risk that led ANSI to "ban" this (IMHO) > perfectly-reasonable bahvior? Order of structure elements is undefined. Zero length arrays are undefined. Also, packing is undefined. You can basically get arouns all of this by declaring the array to be 1 byte, e.g.: struct pargs { u_int ar_ref; /* Reference count */ u_int ar_length; /* Length */ u_char ar_args[1]; /* Arguments */ }; And then sizing the allocation unit relatively, e.g., dont use: sizeof(struct pargs) + byte_count use instead: (int)&((struct pargs *)0)->ar_args + byte_count; To get the size of the elements up to but not including the one byte declared, regardless of alignment or packing. -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
Terry Lambert wrote: | Order of structure elements is undefined. Zero length arrays | are undefined. Also, packing is undefined. Close, but no cigar. The /order/ is defined in C89 (Section 6.5.2.1) with the following words: Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. Greg To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
Thanks for all the very interesting followups, folks. I learned something today! I really must start reading this list more often. :-) -- Conrad Sabatier <[EMAIL PROTECTED]> Bennett's Laws of Horticulture: (1) Houses are for people to live in. (2) Gardens are for plants to live in. (3) There is no such thing as a houseplant. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
On Sun, 3 Mar 2002, Erik Trulsson wrote: ET>On Sun, Mar 03, 2002 at 10:27:17AM -0700, Ian wrote: ET>> > ET>> > In : ET>> > ET>> > /* ET>> > * pargs, used to hold a copy of the command line, if it had a sane ET>> > * length ET>> > */ ET>> > struct pargs { ET>> > u_int ar_ref; /* Reference count */ ET>> > u_int ar_length; /* Length */ ET>> > u_char ar_args[0]; /* Arguments */ ET>> > }; ET>> > ET>> > This does indeed seem to make little or no sense. Could someone explain ET>> > this? Is ar_args supposed to be a pointer or what? ET>> ET>> This is a common technique for defining a structure which is some ET>> descriptive information about an array of objects is followed by an ET>> open-ended array of those objects. (In this case the "objects" are ET>> characters.) The ar_args member of the structure gives a name to that ET>> location in the structure without reserving any space (and thus when the ET>> technique is used, there can only ever be one [0] member and it must be at ET>> the end of the structure). You access the open-ended array of objects just ET>> as you would any other array embedded within a structure, E.G. ET>> instance->ar_args[n]. ET>> ET>> Not all compilers support defining zero-length arrays like this. And that's ET>> a pity; it's an incredibly useful technique, and the alternatives to it are ET>> not nearly as elegant and generally involve ugly recasting of pointers. ET> ET>For those compilers that don't support zero-length arrays one can still ET>use the same trick but with a one-element array at the end of the ET>struct. One just has to remember to that element into account when ET>allocating memory for the structure. Slightly uglier, but not much. ET> ET>It might be worth mentioning that this trick is not actually allowed ET>according to the C standard and in principle invokes undefined ET>behaviour. OTOH, AFAIK the trick does work on all existing compilers, ET>so while it is not standard-conforming it is quite portable. My ISO-C draft copy allows in section 6.7.2.1 paragraph 2 the last member of a structure to be an incomplete array type and paragraph 16 shows an example. Was this removed from the final standard? harti -- harti brandt, http://www.fokus.gmd.de/research/cc/cats/employees/hartmut.brandt/private [EMAIL PROTECTED] To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
On Mon, Mar 04, 2002 at 10:29:18AM +0100, Harti Brandt wrote: > On Sun, 3 Mar 2002, Erik Trulsson wrote: > > ET>On Sun, Mar 03, 2002 at 10:27:17AM -0700, Ian wrote: > ET>> > > ET>> > In : > ET>> > > ET>> > /* > ET>> > * pargs, used to hold a copy of the command line, if it had a sane > ET>> > * length > ET>> > */ > ET>> > struct pargs { > ET>> > u_int ar_ref; /* Reference count */ > ET>> > u_int ar_length; /* Length */ > ET>> > u_char ar_args[0]; /* Arguments */ > ET>> > }; > ET>> > > ET>> > This does indeed seem to make little or no sense. Could someone explain > ET>> > this? Is ar_args supposed to be a pointer or what? > ET>> > ET>> This is a common technique for defining a structure which is some > ET>> descriptive information about an array of objects is followed by an > ET>> open-ended array of those objects. (In this case the "objects" are > ET>> characters.) The ar_args member of the structure gives a name to that > ET>> location in the structure without reserving any space (and thus when the > ET>> technique is used, there can only ever be one [0] member and it must be at > ET>> the end of the structure). You access the open-ended array of objects just > ET>> as you would any other array embedded within a structure, E.G. > ET>> instance->ar_args[n]. > ET>> > ET>> Not all compilers support defining zero-length arrays like this. And that's > ET>> a pity; it's an incredibly useful technique, and the alternatives to it are > ET>> not nearly as elegant and generally involve ugly recasting of pointers. > ET> > ET>For those compilers that don't support zero-length arrays one can still > ET>use the same trick but with a one-element array at the end of the > ET>struct. One just has to remember to that element into account when > ET>allocating memory for the structure. Slightly uglier, but not much. > ET> > ET>It might be worth mentioning that this trick is not actually allowed > ET>according to the C standard and in principle invokes undefined > ET>behaviour. OTOH, AFAIK the trick does work on all existing compilers, > ET>so while it is not standard-conforming it is quite portable. > > My ISO-C draft copy allows in section 6.7.2.1 paragraph 2 the last member > of a structure to be an incomplete array type and paragraph 16 shows an > example. Was this removed from the final standard? I think it is still there (and my draft copy says the same thing). I was thinking about the original C89 standard which does not allow it (and does not allow incomplete array types in structs). Guess I should have said which standard I was referring to. > > harti > -- > harti brandt, >http://www.fokus.gmd.de/research/cc/cats/employees/hartmut.brandt/private > [EMAIL PROTECTED] > -- Erik Trulsson [EMAIL PROTECTED] To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
In message: <[EMAIL PROTECTED]> Erik Trulsson <[EMAIL PROTECTED]> writes: : I think it is still there (and my draft copy says the same thing). : I was thinking about the original C89 standard which does not allow it : (and does not allow incomplete array types in structs). Guess I should : have said which standard I was referring to. struct foo { char array[0]; }; appears to be in C-99 but not C-89. If you have the draft, so far the only thing I've noticed that is different between the draft and the final standard is that there's 10-15 more footnotes in the final standard than were in the final draft. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
On Mon, 4 Mar 2002, M. Warner Losh wrote: MWL>In message: <[EMAIL PROTECTED]> MWL>Erik Trulsson <[EMAIL PROTECTED]> writes: MWL>: I think it is still there (and my draft copy says the same thing). MWL>: I was thinking about the original C89 standard which does not allow it MWL>: (and does not allow incomplete array types in structs). Guess I should MWL>: have said which standard I was referring to. MWL> MWL>struct foo { MWL> char array[0]; MWL>}; MWL> MWL>appears to be in C-99 but not C-89. If you have the draft, so far MWL>the only thing I've noticed that is different between the draft MWL>and the final standard is that there's 10-15 more footnotes in the MWL>final standard than were in the final draft. MWL> MWL>Warner This should be struct foo { char array[]; }; according to C-99, on which gcc2 barfs. Don't know, whether gcc3 can handle this. harti -- harti brandt, http://www.fokus.gmd.de/research/cc/cats/employees/hartmut.brandt/private [EMAIL PROTECTED] To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
>>> Zero length arrays >>> are undefined. >> >> Well, yes, but the quesiton is *why* they are undefined. >> They are undefined only because ANSI says that they are. >> But why did they say so? > > They didn't really. They just didn't say that zero-length arrays are > allowed. (This might be changed in C99, I am not sure.) > > The reason this was not allowed was probably because it was too > difficult to phrase the standard in such a manner that reasonable uses > were allowed, while still not requiring the compiler to handle the > unreasonable cases. Actually in the original standard, zero-length arrays aren't undefined, they're specifically prohibited. Two sections of the standard can be intrepreted as forbidding them... 6.1.2.5 describes an array as "...a continguously allocated non-empty set of objects...". 6.5.4.2 says "The expression delimited by [ and ] (which specifies the size of an array) shall be an integral constant expression that has a value greater than zero." I used to moderate the c_language conference on BIX back in the days when the original ANSI standard was being codified. We used to have endless arguments and discussions about things such as this and the rationale for them, but I don't remember any discussion of this particular issue. (But it was so long ago now it almost seems like another lifetime. I haven't thought about BIX in ages.) -- Ian To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
Erik Trulsson <[EMAIL PROTECTED]> writes: > On Mon, Mar 04, 2002 at 09:35:29AM -0700, M. Warner Losh wrote: > > In message: <[EMAIL PROTECTED]> > > Erik Trulsson <[EMAIL PROTECTED]> writes: > > : I think it is still there (and my draft copy says the same thing). > > : I was thinking about the original C89 standard which does not allow it > > : (and does not allow incomplete array types in structs). Guess I should > > : have said which standard I was referring to. > > > > struct foo { > >char array[0]; > > }; > > > > appears to be in C-99 but not C-89. If you have the draft, so far the > > only thing I've noticed that is different between the draft and the > > final standard is that there's 10-15 more footnotes in the final > > standard than were in the final draft. > > > > Warner > > Are you sure that is in C99? > What is allowed in C99 (but wasn't in C89) is > > struct foo > { > int b; > char array[]; > }; > > Note that you must have a 'normal' field before the incomplete array. > > I don't think >char array[0]; > is allowed in either of C89 or C99. Correct on all counts. I'll cite the letter of the law from C99 if anybody really cares. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
Harti Brandt <[EMAIL PROTECTED]> writes: > This should be > > struct foo { > char array[]; > }; > > according to C-99, on which gcc2 barfs. Don't know, whether gcc3 can > handle this. C-99 requires a fully specified type before the unspecified array (and requires said array to be the last element in the structure). So this example is *not* valid in C99, but the following would be: struct foo { int bar; char array[]; }; [Which makes sense; it forces a structure to have a non-zero size.] To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: A few questions about a few includes
Lowell Gilbert <[EMAIL PROTECTED]> wrote: > >C-99 requires a fully specified type before the unspecified array (and >requires said array to be the last element in the structure). So this >example is *not* valid in C99, but the following would be: > >struct foo { >int bar; >char array[]; >}; > >[Which makes sense; it forces a structure to have a non-zero size.] Although there has been some discussion in the committee about allowing zero-sized objects in C, the standard doesn't allow them. This is perhaps why it doesn't follow gcc's [0] syntax for variable length arrays at the end of structures. Tony. -- f.a.n.finch <[EMAIL PROTECTED]> THAMES DOVER WIGHT PORTLAND PLYMOUTH: WEST OR SOUTHWEST 5 TO 7 DECREASING 4. DRIZZLE DYING OUT. MODERATE, OCCASIONALLY POOR, BECOMING GOOD. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message
Re: Re: A few questions about a few includes
On Mon, Mar 04, 2002 at 09:35:29AM -0700, M. Warner Losh wrote: > In message: <[EMAIL PROTECTED]> > Erik Trulsson <[EMAIL PROTECTED]> writes: > : I think it is still there (and my draft copy says the same thing). > : I was thinking about the original C89 standard which does not allow it > : (and does not allow incomplete array types in structs). Guess I should > : have said which standard I was referring to. > > struct foo { >char array[0]; > }; > > appears to be in C-99 but not C-89. If you have the draft, so far the > only thing I've noticed that is different between the draft and the > final standard is that there's 10-15 more footnotes in the final > standard than were in the final draft. > > Warner Are you sure that is in C99? What is allowed in C99 (but wasn't in C89) is struct foo { int b; char array[]; }; Note that you must have a 'normal' field before the incomplete array. I don't think char array[0]; is allowed in either of C89 or C99. -- Erik Trulsson [EMAIL PROTECTED] To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message