Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uwm.edu!uakari.primate.wisc.edu!samsung!munnari.oz.au!csc!bdm659 From: bdm659@csc.anu.oz Newsgroups: comp.std.c Subject: doubtful assumptions about pointers Message-ID: <1250.25ab3338@csc.anu.oz> Date: 10 Jan 90 13:05:59 GMT Organization: Computer Services, Australian National University Lines: 107 This is an article about the semantics of pointers as defined by the ANSI standard for C (henceforth pANS). It is not necessarily about any existing C compiler, nor about C as defined by any source other than pANS. You probably can't contribute to it significantly unless you have a copy of pANS. If you think that any of my claims are wrong (perfectly possible) then the only way to demonstrate that is via precise reference to the text of pANS. Any quotes from pANS refer to the version of Dec. 7, 1988. Note that some relevant wording changed a lot in the last few revisions. I will call a pointer "valid" if it can be made by a strictly conforming program. There appear to be three kinds of valid pointers: P1: pointers to objects P2: null pointers P3: pointers to "just past" an object (especially array objects, but any pointer to an object can be regarded as a pointer to an array of size one, then incremented once). The following is a list of Doubtful Assumptions (DAs). The definition of a DA is "an assumption that a C programmer might be tempted to make, but which I cannot prove to be justified according to pANS". Determining whether something follows from pANS is not always a simple matter, so some of my DAs might turn out to be not doubtful at all. In fact, I hope I'm wrong about some of them. I'd welcome proofs in either case. DA[0]: int *pi; char *pc; Suppose pi is valid, and do pc = (char*) pi. Then *pc overlaps *pi in the sense that changing the value of *pc changes the value of *pi. DA[1]: int *pi, *pj; char *pc, *pd; Suppose pi and pj are valid, and that pi == pj . Now do pc = (char*) pi; pd = (char*) pj . Then pc == pd . [I bet this one generates some heat. Don't forget to justify your disproof with references to pANS.] DA[2]: Just like DA[1], but using type void* instead of char*. DA[3]: long *pi, *pj; Suppose that pi is valid, and do pj = (long*)(int*) pi; Then pi == pj . [comment: there's no rule that says an int can't have a more strict alignment requirement that a long.] DA[4]: int i, *pi; Suppose pi is a null pointer, and do i = (int) pi . Then i == 0 . DA[5]: Just like DA[4], but with i of type unsigned long . DA[6]: int *pi, *pj; Suppose pi is valid, and do pj = (int*)(unsigned long) pi. Then pi == pj . DA[7]: int i, *pi; Suppose i != 0, and do pi = (int*) i . Then pi != (int*)0 . DA[8]: int *pi, *pj; Suppose pi is a valid pointer of kind P3, and do pj = (int*)(char*) pi . Then pi == pj . [comment: the rule in section 3.3.4 only applies to pointers to objects, which pi might not be.] DA[9]: int *pi; Suppose that an external function f() is declared without prototype. It expects a single argument of type void*. Assume that pi is valid. Then the call f(pi) works. [comment: See my remarks on section 3.1.2.5 below.] DA[10]: void *pv; external void *f(); In fact, f returns a value of type int*. Then pv = f() works. [comment: See my remarks on section 3.1.2.5 below.] References and some nit-picking. 1.6. definitions of "object" and "alignment" 3.1.2.5. types and type terminology definitions of "object type" and "incomplete type" nit-pick: This section several rules of the form "types X and Y have the same representation and alignment requirements". Footnote 15 tells us that this is intended to imply interchangeability as function arguments, function return values, and members of unions. However, this does not follow from the rule. Interchangeability of two types as function arguments requires, in addition, equality of argument-passing mechanisms. This is nowhere prescribed. 3.2.2.3. conversions amongst pointer types, null pointers 3.3.2.1. array subscripting 3.3.3.2. * and & operators 3.3.4. more on conversion amongst pointer types conversions between integral types and pointers nit-pick: The case of (obj*)0 should be excluded from these rules as it is specified differently in 3.2.2.3. 3.3.6. pointer + integer, pointers just past an object 3.3.8. relational operators nit-pick: The phrase "or both are null pointers" is missing from the sentence in lines 8-10. See the otherwise identical sentence in section 3.3.9. 3.3.9. equality operators 3.3.16.1. simple assignment 3.5.2.1. conversions between pointers to union members =========================================================== Brendan McKay. bdm@anucsd.oz.au or bdm659@csc1.anu.oz.au terrorist: n. an individual who behaves like a government (original)