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,616091a85ff150f1 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-12-16 22:43:12 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!arclight.uoregon.edu!wn4feed!worldnet.att.net!135.173.83.71!wnfilter1!worldnet-localpost!bgtnsc06-news.ops.worldnet.att.net.POSTED!not-for-mail From: "David Thompson" Newsgroups: comp.lang.ada References: <3C0C48BE.3B20F04E@adaworks.com> Subject: Re: Ada 200X Assertions 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: <3ugT7.228176$3d2.10813449@bgtnsc06-news.ops.worldnet.att.net> Date: Mon, 17 Dec 2001 06:43:11 GMT NNTP-Posting-Host: 12.89.135.204 X-Complaints-To: abuse@worldnet.att.net X-Trace: bgtnsc06-news.ops.worldnet.att.net 1008571391 12.89.135.204 (Mon, 17 Dec 2001 06:43:11 GMT) NNTP-Posting-Date: Mon, 17 Dec 2001 06:43:11 GMT Organization: AT&T Worldnet Xref: archiver1.google.com comp.lang.ada:17979 Date: 2001-12-17T06:43:11+00:00 List-Id: Lutz Donnerhacke wrote : ... > Typical example 1: A common termination node of linked lists. > Typical example 2: A head node of a linked list contains a next pointer which > should be handled exactly as the next pointer of the real > list nodes, but no payload at all. > > It would be fine to generate a pointer from this component to a 'virtual' > aggregate of the given type. > ("Virtual" in the sense that it is a struct/record that isn't stored, but the link field within it would overlay the head link or whatever.) > Example: > struct node { > ... data ... > struct node * next; > } > struct head { > struct node * next; > } > > struct head h; > h.next = &h - sizeof (node) + sizeof (head); > This is quite wrong for C, or C++; pointer arithmetic works in units of the size of the type pointed to (and the conversion cannot be implicit). Assuming you meant: h.next = (struct node *) ( (char*)&h + sizeof(struct head) - sizeof(struct node) ); /* 'struct' can be omitted in C++, or in C if you also typedef struct x ... x */ or, equivalent and arguably more elegant: h.next = (struct node *)(&h + 1/*head*/) - 1/*node*/; 1) this isn't portable -- neither the C nor C++ standard defines/guarantees computing pointers outside (before) an object, except that you can compute (but not dereference) a pointer "to" the end of an array or past a non-array object to support idioms like: char x[10] = "foo", * p; for( p = x; p < &x[10] /* or x+10 */; p++ ) *p = 'x'; Even computing, much less using, your "virtual" pointer is Undefined Behavior, meaning the implementation is not required to check/catch/diagnose it or even work at all. 2) even on mainstream platforms where (C or C++) pointers are just numbers, and subtracting and adding back an offset does work reliably, that may be the wrong offset if struct node is more strictly aligned than struct head, which is quite possible. _This_ problem you can portably fix with: h.next = (struct node *) ( (char*)&h - offsetof(struct node,next) ); which also works for link fields not at the "end" of the structure, and is a more direct representation of what you are doing to boot. I would expect that on any system where this works for C/C++ the Ada equivalent with 'Address and 'Position works as well. -- - David.Thompson 1 now at worldnet.att.net