Newsgroups: comp.std.c Path: utzoo!sq!msb From: msb@sq.sq.com (Mark Brader) Subject: Re: X3J11 Pleasanton meeting summary Message-ID: <1990Oct11.203338.16419@sq.sq.com> Organization: SoftQuad Inc., Toronto, Canada References: <1990Oct3.184359.2348@sq.sq.com> <1737:Oct803:02:5890@kramden.acf.nyu.edu> <14049@smoke.BRL.MIL> Date: Thu, 11 Oct 90 20:33:38 GMT Lines: 59 To Doug Gwyn's summary: > int a[4][5]; > a[1][7] = 0; /* undefined behavior */ > Dave Prosser (our Redactor) vigorously protested ... I wrote: @ My opinion is that the protest was right and the ruling wrong. Doug then posts a longer form of the ruling: : For an array of arrays, the permitted pointer arithmetic in : Standard section 3.3.6 Semantics (p. 48, ll. 12-40) is to be : understood by interpreting the use of the word "object" as : denoting the specific object determined directly by the pointer's : type and value, NOT other objects related to that one by contiguity. I now see that this is right, I was wrong, and it is undefined behavior. But this leads to a problem, which I'll get to in a moment. First, I should explain my error. In reply to Karl Heuer's comment: ! I presume that this ruling (if upheld) also means that strictly conforming ! programs may not use extensible structs via the usual overmalloc hack? Alan Rosenthal writes: | Alternatively, (int (*)[5])malloc(4 * 5 * sizeof(int)) may be deemed to | create an object viewable as being 20 ints even though int a[4][5] does | not, in which case the overmalloc hack would still be fine (though | blecherous). And I agree with this also. This was in fact the source of my original confusion: I had previously examined the wording carefully to ensure that the "overmalloc hack" was legal, remembered the conclusion, and forgotten the reasoning behind it. I then assumed that as I knew the conclusion I didn't need to go back to the Standard and see the actual wording. Stupid. Now the problem. Doug also notes: > Note that even such a subterfuge as the following would not be strictly > conforming: > void func( int *p ) { p[7] = 0; } > int main( void ) { int a[4][5]; func( a[1] ); return 0; } And I agree with this also. p points to the element a[1][0] in the array a[1], and there is no element [7] in that array, so it's undefined. But what if func was written as follows? void func (void *p) {int *ip = p; ip[7] = 0; } Does ip also point to the element a[1][0] in the array a[1], and is this therefore still non-conforming? If so... can memcpy() really be implemented in ANSI C, and used to copy arbitrary objects? -- Mark Brader "It's easier to deal with 'opposite SoftQuad Inc., Toronto numbers' when you know you cannot utzoo!sq!msb, msb@sq.com trust them." -- Chess This article is in the public domain.