Context
I am working on a computational fluid dynamics code where I work with vector and matrices. Consequently I want to pass them to functions every once in a while.
The memory for vectors and matrices is allocated as follows consequently throughout the code
double* vec = calloc(n, sizeof(double));
double* mat = calloc(n * m, sizeof(double));
meaning I would like to access matrices like this mat[i * m + j]
.
In order to "auto-document" functions I would like to include the size of these arrays into the function prototype. For vectors this works flawlessly and looks something like this
// vecmat.h
void vec_print(size_t n, double const vec[restrict n]);
// vecmat.c
void vec_print(size_t n, double const vec[restrict n])
{
for (size_t i = 0; i < n; ++i) {
printf(DBL_FMT, vec[i]);
}
putchar('\n');
}
Problem
To keep things consistent, I would like to do the same thing with matrices, so I did this
// vecmat.h
void mat_print(size_t n, size_t m, double const mat[restrict n * m]);
// vecmat.c
void mat_print(size_t n, size_t m, double const mat[restrict n * m])
{
for (size_t i = 0; i < n; ++i) {
for (size_t j = 0; j < m; ++j) {
printf(DBL_FMT, mat[i * m + j]);
}
putchar('\n');
}
putchar('\n');
}
Here comes the issue though. When I compile, I get the following warning
src/vecmat.c:21:49: warning: argument 3 of type ‘const double[restrict n * m]’ declared with mismatched bound ‘n * m’ [-Wvla-parameter]
21 | void mat_print(size_t n, size_t m, double const mat[restrict n * m])
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/vecmat.c:1:
src/vecmat.h:16:49: note: previously declared as ‘const double[restrict n * m]’ with bound ‘n * m’
16 | void mat_print(size_t n, size_t m, double const mat[restrict n * m]);
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
The code compiles fine and also produces the expected output, but I would like to get rid of the warning message. I know that C does not use the provided dimension n * m
of the array, but rather silently converts the argument into double* restrict mat
. The problem seems to have something to do with the fact that I am using a multiplication and gcc
somehow thinks that the array bounds are inconsistent.
Question
Can I somehow modify my syntax to avoid this compiler warning, or can I somehow disable this warning in gcc
altogether? (gcc
does not have the flag -Wno-vla-parameter
)
EDIT -Wno-vla-parameter
does exist and removes the warnings
Solution
Matrices should be allocated as follows:
double (*mat)[m] = calloc(n * sizeof(*mat));
The function calls with matrices in them should be altered as follows:
void mat_print(size_t n, size_t m, double const mat[restrict n][m]);
This makes it possible to access the matrix elements in a simpler form mat[i][j]
.
Unfortunately gcc still complains, because the function uses const
. (https://godbolt.org/z/6xh5Exsff) If this also has a clever fix my initial and all subsequent problems would be solved :D
Additional resources:
Additional Info
gcc
version 11.1.0-std=c99