Re: array subscript type cannot be `char`?
- From: Chris Torek <nospam@xxxxxxxxx>
- Date: 23 Mar 2006 19:30:39 GMT
In article <1143109948.061060.162080@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>
<ena8t8si@xxxxxxxxx> wrote:
void *v;
int *p;
int a[4][5];
/*1*/ v = &a;
p = (int*)((char*)v + 5 * sizeof(int));
p[7] = 0;
/*2*/ v = &a;
p = (int*)v + 5;
p[7] = 0;
/*3*/ v = a;
p = (int*)v + 5;
p[7] = 0;
/*4*/ p = a[1];
p[7] = 0;
/*5*/ (p = a[1])[7] = 0;
/*6*/ (a[1])[7] = 0;
/*7*/ a[1][7] = 0;
At what point in 1-7 does the behavior become undefined?
Remember, the DR says that "object" means "the specific object
determined directly by the pointer's _type_ and _value_."
Note: I am not sure whether I *agree* with the argument I am about
to present. I merely *present* it.
Someone -- I think Doug Gwyn -- said that the (or "an") aim of the
rules here is to allow a compiler to "cheat" by, internally, tagging
pointers with additional information about the size(s) of the
underlying object(s) from which the pointers are derived.
Imagine for a moment a machine in which "add integer value that
does not exceed 10 to pointer" is one million times faster than
"add any integer to pointer". Suppose that sizeof(int) is 2, so
that sizeof(a[0]) is 10. Suppose that the fast add gives the
"wrong" result if the integer is greater than 10 (presumably,
produces a sum that is smaller than the desired result).
Now, for (1) through (3) above, the compiler is probably forced to
use the million-times-slower addition to compute p[7]. In (4),
it probably still uses this. In (5), the compiler may have a little
more information, and by assignment 6, the compiler *definitely*
has more information.
In particular, in assignment 6, the compiler is allowed to "know"
that a[1] is an "array 5 of int" so that sizeof a[1] is 10. It
can therefore use the "fast add" to add 14 to the pointer, on the
assumption that the integer (14) must be 10-or-less (even though
it is not). This, of course, gives the "wrong" result, addressing
a[1][2] or a[1][3] or some such (maybe even halfway between the two).
According to this argument, the behavior becomes undefined
somewhere around assignment 5 or 6, and is definitely undefined
by assignment 7.
Obviously, real machines do not have instructions like "add restricted
integer not exceeding 10 to pointer" -- but they *do* have
range-restricted instructions. A compiler for a CPU like the 80186
might want to use 16-bit addition to address "small" arrays (with
segment:offset addressing), and 32-bit addition to address "large"
arrays (still with segment:offset but now using the full 20-bit
addressing mode, doing normalization and so on, instead of assuming
that the entire array fits in a single segment).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
.
- Follow-Ups:
- References:
- array subscript type cannot be `char`?
- From: Pedro Graca
- Re: array subscript type cannot be `char`?
- From: Keith Thompson
- Re: array subscript type cannot be `char`?
- From: Robert Gamble
- array subscript type cannot be `char`?
- Prev by Date: Re: XML Parsing
- Next by Date: Re: How to know the size of array
- Previous by thread: Re: array subscript type cannot be `char`?
- Next by thread: [ot]Re: array subscript type cannot be `char`?
- Index(es):
Relevant Pages
|