home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!crdgw1!rdsunx.crd.ge.com!bart!volpe
- From: volpe@bart.NoSubdomain.NoDomain (Christopher R Volpe)
- Newsgroups: comp.lang.c
- Subject: Re: Is this ANSI?
- Message-ID: <1992Nov23.175310.2216@crd.ge.com>
- Date: 23 Nov 92 17:53:10 GMT
- References: <9eRguB1w165w@quest.UUCP> <24238@alice.att.com> <1992Nov21.125038.26244@sq.sq.com> <24270@alice.att.com>
- Sender: volpe@bart (Christopher R Volpe)
- Reply-To: volpe@ausable.crd.ge.com
- Organization: GE Corporate Research & Development
- Lines: 172
- Nntp-Posting-Host: bart.crd.ge.com
-
- In article <24270@alice.att.com>, ark@alice.att.com (Andrew Koenig) writes:
- |> In article <1992Nov21.125038.26244@sq.sq.com> msb@sq.sq.com (Mark Brader) writes:
- |>
- |> > Andrew, I'm afraid that *you* are definitely wrong, period.
-
- I agree with Mark.
-
- |>
- |> After thinking it over carefully, I'm not convinced.
- |>
- |> > The key word here is "allocate", meaning that the intention is to
- |> > do something like
- |>
- |> > struct FM *p = malloc (sizeof (struct FM) + n);
- |>
- |> Agreed.
-
- [stuff deleted]
-
- |>
- |> Unfortunately, I wasn't in on that discussion. But to convince me
- |> that it's legal, you'd have to find language in the standard that allows
- |> it. I looked around a little bit, and here is what I found, in the description
- |> of pointer+integer:
- |>
- |> Unless both the pointer operand and the result point to
- |> elements of the same array object, or the pointer
- |> operand points one past the last element of an array
- |> object and the result points to an element of the same
- |> array object, the behavior is undefined if the result
- |> is used as an operand of the unary * operator.
- |>
- |> Now, let's take a look at the example again:
- |>
- |> struct FM {
- |> int size;
- |> char data[1];
- |> };
- |>
- |> main()
- |> {
- |> struct FM *p = (struct FM *) malloc(sizeof(struct FM) + 100);
- |> p->data[5] = '?';
- |> }
- |>
- |> At issue is the assignment to p->data[5].
- |>
- |> As I see it, the question is just what p->data is. If I look at the
-
- p->data, as operand to the "[]" operator, decays into a pointer-to-char.
- It points somewhere within the block returned by malloc().
-
- |> definition of p, I see that p->data is an array of char with one element.
-
- After it decays, it no longer has array type.
-
- |> The way I've used it is, of course, equivalent to *(p->data+5).
- |>
- |> That means p->data is converted to a pointer to its initial element,
- |> namely a pointer to the first (and only) element of a one-element array.
- |> [Remember this assertion]. So, we take that pointer, add 5 to it,
- |> and apply unary * to the result. Well, the pointer operand of +
- |> points to an element of the array object, but the result does not;
- |> there is only one element and the result doesn't point there.
- |> The result of using unary * is therefore undefined.
-
- Both the operand and result point within the array-of-char returned by
- malloc.
-
- |>
- |> Now, look back at the assertion I asked you to remember. I expect
- |> that Mark Brader is going to say `But p->data isn't an array of
- |> one element, it's an array of 101 elements. After all, when you
- |> said malloc(sizeof(struct FM + 100), you allocated enough memory
- |> for 101 elements!'
- |>
- |> Here are two reasons I disagree:
- |>
- |> 1. Suppose I said
- |>
- |> struct FM *q = (struct FM *) malloc(sizeof(struct FM) + 100);
- |>
- |> and later said
- |>
- |> *p = *q;
- |>
- |> Is the compiler obligated to realize that p and q actually point
- |> to objects of type other than struct FM? That is, is it obligated
- |> to copy all the `extra' elements in the data array?
-
- Of course not. This is a bogus argument. Consider this:
- int i[100];
- int *p, *q=i;
- p = malloc(100 * sizeof(int));
-
- Now, if I do:
-
- *p = *q;
-
- Is the compiler obligated to realize that p and q, which are declared as
- "pointer to int", actually point to something other than single ints?
- Should it copy the entire array? Of course not. Does this mean that p[5]
- is an illegal reference?? Of course not. Otherwise, to allocate dynamic
- arrays of ints, one would have to do:
-
- typedef int array[100];
- array *p;
- p = (array *) malloc(sizeof(array));
- /* blah blah blah */
- (*p)[5] = whatever;
-
-
- |>
- |> 2. If you declare p by saying
- |>
- |> struct FM *p;
- |>
- |> then I don't think there is any place in the standard that says
- |> other than that *p is an lvalue of type FM. Once you acknowledge
- |> that *p is of type FM, I don't see how you can get away from the
-
- Yes, *p is of type FM, just as in my example, *p was of type int.
- It's still not relevant.
-
- |> p->data being anything other than a one-element array. What I found
- |> in the standard that talks about this is:
- |>
- |>
- |> The pointer returned [by malloc or realloc] if the
- |> allocation succeeds is suitably aligned so that it
- |> may be assigned to a pointer to any type of object
- |> and then used to access such an object or an array
- |> of such objects in the space allocated (until the
- |> space is explicitly freed or reallocated).
- |>
- |> It doesn't say that it may be assigned to a pointer to some
- |> type of object and then used to access an object of some other
- |> type. That is, it says that the result of malloc may be
- |> assigned to a struct FM * and then used to access an object
- |> of type struct FM. It says nothing about struct FM representing
- |> a family of related types.
-
-
- There's no family of related types here. The type of interest is "char *",
- which is what p->data decays into.
-
- |>
- |> Another way to look at it is this. Suppose I have a compiler that rejects:
- |>
- |> void f(struct FM *p)
- |> {
- |> p->data[5] = '?';
- |> }
- |>
- |> on the basis that p->data is a one-element array and you can't refer to
- |> the fifth element of a one-element array. What part of the standard can
- |> you cite to convince me that my compiler isn't allowed to diagnose this?
-
- It can diagnose it at runtime if it can determine that p->data and
- p->data+5 don't point within the same object. If it tries to do this at
- compile-time, file a bug report.
-
- |> -- especially after the description of pointer arithmetic above?
- |> --
- |> --Andrew Koenig
- |> ark@europa.att.com
-
- --
- ==================
- Chris Volpe
- G.E. Corporate R&D
- volpecr@crd.ge.com
-