Here is a way to define a Matrix type
typedef struct {
int nr, nc;
double *elem;
} Matrix;
I would like to define this
typedef struct {
int nr, nc;
double elem[nr][nc];
} Matrix;
It would be nice, because I would not have to worry about indexes. That's the reason VLA are useful in the first place, since they only do transparently what would be easy with index arithmetic.
Of course, the above is not possible, if only because the size of the struct would not be well defined. Then, I would still be happy with:
typedef struct {
int nr, nc;
double (*elem)[nc];
} Matrix;
Now, the matrix data is stored as a pointer, like in the non-VLA case. But the arithmetic could still be done by the compiler. The definition only tells it's some kind of pointer to double
data, with the doubles arranged in an array of width nc
.
It seems that it's not permitted either by the standard, and I wonder why, since it's easy to do the same by transtyping. For example, using the first definition (with double *
), I could do
double get(Matrix *a, int i, int j) {
int nc = a->nc;
double (*p)[nc] = (double (*)[nc])a->elem;
return p[i][j];
}
Of course, it's not very interesting here, since there is only one access to elem, but it could be if there are many.
So, my question, with the hope that it's on topic: what's the very reason of prohibiting the third definition?
I could imagine that it's dangerous since it's not guaranteed that nc
handles the correct value, but this is dangerous anyway with pointers, so it does not look like a good reason.