>Keith Thompson wrote:
>>As far as I can tell, VLAs of VLAs are permitted.
(They are, necessarily so.)
In article <>,
CBFalconer <> wrote:
>I differ. Arrays need to be composed of equal sized objects.
>VLAs, by nature, are variable sized objects.
This is the tricky part: while VLAs are "variable length arrays",
each *instance* of any given VLA is fixed-size.
VLAs of VLAs are necessary because one of the goals, perhaps even
the primary goal, of VLAs in the first place was to allow C
programmers to write Fortran-like functions with Fortran-like
convenience, e.g.:
/* perform some operation on a matrix of "double" */
void mat_operate(size_t m, size_t n, double mat[m][n]) {
size_t i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
... operate on mat[i][j] ...
}
When mat_operate() is called, m and n are variable, but while
mat_operate() operates, m and n remain fixed. The size of the
matrix "mat" is also fixed.
(This remains true even if m and/or n are modified inside mat_operate().
The size is, in effect, "captured" at the point the VLA is created.)
The key sentences in my draft read:
The size of each instance of a variable length array type
does not change during its lifetime.
and (in part):
... the size of the variable length array type does not change
if the value of n is subsequently changed.
>You could have an array of pointers to VLAs, though.
You can indeed have this, as well. You can also have a VLA of
pointers to VLAs, and so on.
The compile-time compatibility rules for pointers to VLAs are
quite relaxed, with the effect at runtime being undefined if the
sizes of the variably-modified types do not match:
void f(size_t n, double square_mat[n][n]) {
double (*p)[rand()]; /* bad idea, for illustration only */
p = square_mat; /* not a compile-time error */
...
}
The effect is undefined unless n happens to be equal to the
value rand() returns. In practice, in a real C compiler, if
rand() returns a number that does not match n, p[0][j] "works
right" but p[i][j] misbehaves: If we were to capture the
number that came out of the rand() call, e.g., via:
size_t x;
double (*p)[x = rand()];
instead, then p[i][j] is roughly equivalent to mat[0][i * x + j]
as long as no subscript checking occurs. (Of course, because of
the undefined behavior, the compiler can make various assumptions
and optimize this particular weirdness into *other* weirdness.
For instance, it might make the assumption that x must necessarily
equal n, hence remove x from the runtime image and use the saved
n -- so that p[i][j] accesses mat[i][j] after all!)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.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.