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-07-30 20:06:04 PST Path: archiver1.google.com!newsfeed.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!news.stealth.net!204.127.161.2.MISMATCH!wn2feed!worldnet.att.net!135.173.83.71!wnfilter1!worldnet-localpost!bgtnsc06-news.ops.worldnet.att.net.POSTED!not-for-mail Message-ID: <3B662129.D6055BAA@worldnet.att.net> From: James Rogers X-Mailer: Mozilla 4.76 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: type Foo_ptr in new void*; 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> <9k517e$rbh$5@news.tpi.pl> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Tue, 31 Jul 2001 03:06:02 GMT NNTP-Posting-Host: 12.86.37.125 X-Complaints-To: abuse@worldnet.att.net X-Trace: bgtnsc06-news.ops.worldnet.att.net 996548762 12.86.37.125 (Tue, 31 Jul 2001 03:06:02 GMT) NNTP-Posting-Date: Tue, 31 Jul 2001 03:06:02 GMT Organization: AT&T Worldnet Xref: archiver1.google.com comp.lang.ada:10807 Date: 2001-07-31T03:06:02+00:00 List-Id: Tomasz Wegrzanowski wrote: > > In article <3B64C26F.C195B4E0@worldnet.att.net>, James Rogers wrote: > > Yes, you are correct. C does allow you to forward declare a structure > > or a pointer without ever completing the definition. This is one of > > the nasty capabilities "provided" by C. You can even create an array > > of Foo *. However, pointer arithmetic from the start of this array > > produces unspecified behavior. What is the sizeof Foo? Since it 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. > > Correct answer is compilation error. > It's illegal to do pointer arith on void* or incomplete types. It is illegal, but not necessarily caught by the compiler. This means that the correct answer is not compilation error. C compilers are actually pretty primitive in their understanding of data type completion. They rely on highly intelligent linkers to find all the completions. Unfortunately, linker diagnostic messages are a lot less useful than compiler diagnostic messages. One reason is that the linker has no understanding of source code line numbers. It cannot tell you where the problem occured beyond the name of the object file it came from. Given the C #include technology, you cannot even directly relate the object file name with the source file name in all cases. A single object file could have been created from one or several source files. Even more problems arise when using shared libraries or DLLs. In that case the linker cannot find all the required pieces. Only the program loader will find them. Your compiler and linker may execute without error. Your loader will be left to try to identify all the missing pieces. Loader error messages are even poorer than linker error messages. What does it mean, then, when a function returns a void*? You are allowed to cast that void* to any other pointer type you want. Once cast, you are allowed to perform pointer arithmetic on it. If you do not TRULY know the type of the data pointed to by a void*, and then you cast it to some type, expecting correct results, you will sometimes get a nasty surprise. Pointer arithmetic will be performed, but your view of the data will be incorrect due to poor alignment problems. > > > In other words, you can declare some wonderful data structures in C > > based on incomplete type definitions. Unfortunately, a program built > > upon such a structure is neither reliable nor portable. > > It's both portable and reliable. It is portable because it causes the same kinds of problems wherever used. You can rely on this feature to be dangerous. For instance, an array of incomplete data types, or pointers to the same, will cause a violation of the rules you state above. That array can be created, but not manipulated. In C, all array element access involves pointer arithmetic. This is true even when using array indexing directly. The compiler simply substitutes pointer arithmetic for the indexing notation. > > > Ada does not allow you to compile a program with an incomplete type > > definition. There is no equivalent because the existence of an > > equivalent to this C capability would only introduce errors in your > > program. There is nothing positive that can be achieved by allowing > > a program to be incompletely specified. > > Sure, if your favourite language has no feature X, > then feature X is useless. Ada does not have this feature because its danger was judged to outweigh its value. That does not make this feature useless. It only makes it unsafe. > Incomplete types warrant opacity. This is important in C because of its lack of private data types. More modern languages achieve opacity without sacrificing program safety. Jim Rogers Colorado Springs, Colorado USA