From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,4deb6c62a5e19f2 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-08-03 23:05:06 PST Path: archiver1.google.com!newsfeed.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!wn1feed!worldnet.att.net!135.173.83.71!wnfilter1!worldnet-localpost!bgtnsc04-news.ops.worldnet.att.net.POSTED!not-for-mail From: "David Thompson" Newsgroups: comp.lang.ada References: <9k03jc$2me$2@news.tpi.pl> <9k0j60$n4t$1@news.tpi.pl> <3B63F48A.2E2642C6@earthlink.net> <9k2btj$5hj$1@news.tpi.pl> <3B64C26F.C195B4E0@worldnet.att.net> <3B663A70.3B315EC8@san.rr.com> Subject: Re: type Foo_ptr in new void*; X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.00.2615.200 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200 Message-ID: Date: Sat, 04 Aug 2001 06:05:05 GMT NNTP-Posting-Host: 12.89.143.249 X-Complaints-To: abuse@worldnet.att.net X-Trace: bgtnsc04-news.ops.worldnet.att.net 996905105 12.89.143.249 (Sat, 04 Aug 2001 06:05:05 GMT) NNTP-Posting-Date: Sat, 04 Aug 2001 06:05:05 GMT Organization: AT&T Worldnet Xref: archiver1.google.com comp.lang.ada:11283 Date: 2001-08-04T06:05:05+00:00 List-Id: Darren New wrote : ... > > Since [sizeof a C incomplete struct type namely Foo] is > > undefined, there is no correct answer to that question. Without a > > proper definition of the sizeof Foo, there can be no reliable pointer > > arithmetic. > > Right. That's why you can't do pointer arithmetic on a Foo* without > defining Foo. > One thing the previous poster might have been thinking of is that in C89/90 you could _declare_ as "extern" an array of an incomplete type; you might also be able to declare/define a function (formal) parameter as array of incomplete since that can be "adjusted" to a pointer, and pointer to incomplete is fine, although the WG response to Defect Report 047 held that this is not guaranteed; you could also define a typedef for array-of-incomplete if ultimately used only as above. You could _define_ (allocate) an actual array object only with a complete element type. Since you can't do pointer arithmetic (and thus []) on it, the only thing you could do with an array-of-incomplete was pass its address (pointer) to some other code which _does_ know about the completed type. In C99, this feature(?) is gone; it is now a constraint (6.7.5.2p1) on the array declarator that the element type must be complete in all cases, and thus a required diagnostic if not (see below). (But even when compilers start supporting C99, I expect some, maybe many, will still have options to get C89 behavior.) > Which is not to say that Ada isn't superior to C in this respect. > In particular, in C it is the programmer's responsibility to have different translation units (roughly, source files) use identical definitions (or nearly so) for a struct type. It is easy to get this wrong; the implementation is not required to detect it; and many, probably most, don't, since the compile+link model doesn't normally support it, although it would be legal. (I do know one implementation where the linker checks that function parameters which are pointers agree on the _size_ of the target; this doesn't catch all errors, but does help a good bit. I think it does so primarily because it needs this info in the object file for Fortran and COBOL, and C goes along for the ride.) Actually writing different definitions in two different sources is fairly obvious, but there are subtler ways to screw up. One is to change the definition in a .h file and recompile some but not all of the .c's that use it; tools like make help with this. Another is to have two same-named .h files in different directories/subtrees and select a wrong one. A third is to actually include the correct and same .h but it in turn uses #define's which are set differently (a coworker recently lost several days to that last; even a full de novo build doesn't catch or fix it). > But what do you think a compiler is going to do if you index an array of > Foo without defining Foo? Just randomly make up a sizeof(Foo) from whole > cloth? There's probably something in the standard about this. > If anyone really cares (from C99 = ANSI/ISO/IEC 9899:1999) - 6.5.2.1 defines subscripting (partly) in terms of pointer addition - 6.5.6p2 requires in a constraint that (one) operand of pointer addition be "to an object type" - 6.2.5p1 defines "object type" to exclude incomplete types. (Those places in the standard that want to allow incomplete types say "object or incomplete type".) - 6.5.3.4p1 requires in a constraint that sizeof "shall not be applied to ... an incomplete type ..." (sizeof is not actually used in the _definition_ of pointer arithmetic directly, although that's the usual implementation, only indirectly through 6.2.5p20 array elements are contiguous) - 5.1.1.3 requires "at least one diagnostic message" if there is "a violation of any syntax rule or constraint" -- although the standard doesn't require _useful_ diagnostics; it is only a nonnormative footnote that it _should_ "identify the nature of, and where possible localize, each violation." Having diagnosed a violation, the implementation is permitted to do anything whatsoever, even continue to translate and execute; this is Undefined Behavior "on which this International Standard imposes no requirements" (much like Ada Unbounded Error). If a compiler writer was silly enough to think that a random (more likely pseudorandom) sizeof here was a good idea, they could. More plausible is to just use whatever value happens to be in some slot of the symbol table that would be correct for a complete type but isn't valid (wasn't set) for incomplete. HAND. -- - David.Thompson 1 now at worldnet.att.net