Re: Pointer arithmetics in 2D arrays
- From: "Army1987" <please.ask@xxxxxx>
- Date: Fri, 18 May 2007 15:35:53 +0200
"Pierre Asselin" <pa@xxxxxxxxxxxxxxxxxxxxx> ha scritto nel messaggio
news:f27iuq$oki$1@xxxxxxxxxxxxxxxxxxxx
Richard Heathfield <rjh@xxxxxxxxxxxxxxx> wrote:Here the Standard quietly whispers what the behaviour is, but officially
Army1987 said:
print_square_matrix(*matrix, 3);
matrix has type int[3][3], which decays to int(*)[3] when used in a
value context. So *matrix has type int[3] - but you use this in a value
context too, so it becomes int *. That's legal to pass to
print_square_matrix, which takes int *. But in print_square_matrix, you
are, strictly speaking, breaking the rules. Why? Well, you pass a
pointer that points to the first element in an array of three ints, but
you roll through nine ints in your function. Therefore, you're
overstepping the bounds of an array.
Such a strict interpretation would cripple the use of C in numerical
computations. I don't think that was the intent, based in part on a
a similar example I noticed in the C99 Rationale v5.10, end of
section 6.7.5.3 .
<quote>
void g(double *ap, int n)
{
double (*a)[n] = (double (*)[n]) ap;
/* ... */ a[1][2] /* ... */
}
[ ... ] the function g can be called as in
{
double x[10][10];
g(&x[0][0], 10);
}
</quote>
The cited example has "&x[0][0]" as opposed to "*matrix" in the
orignal post, but that seems like a very subtle distinction. In
the Rationale code, "x[0][0]" is a mere scalar and "&x[0][0]" is
its address, but it is clear that g() is allowed to treat this
address as the start of an array of 100 doubles. (The example
goes on to show how to view said array as a two-dimensional object
by means of a VLA, but that's beside the point here.)
So in my view, the OP's code is de-facto valid C (C89 since he
doesn't use a VLA). If the OP needs to survive a code review, he
could write
print_square_matrix(&matrix[0][0], 3);
and cite the C99 rationale 6.7.5.3 in a comment.
says it is undefined. Annex J, under "Undefined behaviour":
An array subscript is out of range, even if an object is apparently
accessible with the
given subscript (as in the lvalue expression a[1][7] given the declaration
int
a[4][5]) (6.5.6).
(I wasn't aware that there has been an implementation which actually checks
array bounds, since I thought that would defeat the purpose why array
overflow was declared UB in the first place (i.e. speeding up run time by
trusting the program). But if there is one, I understand why even
overflowing the innermost array is UB.)
.
- Follow-Ups:
- Re: Pointer arithmetics in 2D arrays
- From: Richard Heathfield
- Re: Pointer arithmetics in 2D arrays
- References:
- Pointer arithmetics in 2D arrays
- From: Army1987
- Re: Pointer arithmetics in 2D arrays
- From: Richard Heathfield
- Re: Pointer arithmetics in 2D arrays
- From: Pierre Asselin
- Pointer arithmetics in 2D arrays
- Prev by Date: Re: Comparing Bits....
- Next by Date: Re: portability problem with a function returning a struct
- Previous by thread: Re: Pointer arithmetics in 2D arrays
- Next by thread: Re: Pointer arithmetics in 2D arrays
- Index(es):
Relevant Pages
|