简体   繁体   中英

How can I define a pointer to variable length array (VLA) in a struct (or equivalent)?

I declared many pointers to variable length array (VLA) in a function to allocate 2-D arrays dynamically; for example,

int M, N; // have some value
double (*arr1)[N] = calloc(M, sizeof(double [N]));
double (*arr2)[N] = calloc(M, sizeof(double [N]));
double (*arr3)[N] = calloc(M, sizeof(double [N]));
... // so many declarations

Because the function became very long, I tried to split it into several functions, each of which requires all that pointers as the argument. Instead of passing many things in the function (which is bad for a performance), I declared a struct containing all pointers globally to reduce the number of argument:

struct ptrpack {
    int M, N;
    double (*arr1)[N];
    double (*arr2)[N];
    ...
};

// then each function just takes a single struct rather than many pointers
void foo(struct ptrpack p) {
    ...
}

However, a pointer to VLA is not allowed in struct. GCC extension allows it if the struct definition is in a function, but the definition is in global scope in my case.

What is the best solution for this problem? I strongly prefer to use a pointer to VLA, not an ordinary pointer.

Declare the structure members to be pointers to arrays of unknown size (no size expression is supplied in the brackets):

double (*arr1)[];

Such pointers are compatible with pointers to variable length arrays because pointers to compatible types are compatible (C 2018 6.7.6.1 2), and an array of unknown size is compatible with any array with a compatible element type, per 6.7.6.2:

For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value…

Because the pointer type does not indicate the array size, you will not be able to use these members directly to access multiple dimensions. For example, if p is the structure, p.arr1[i][j] will yield a compiler error. One way to use them is to assign them to temporary variables that include the type information:

double (*arr1)[p.N] = p.arr1;
… // arr1[i][j] works here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM