使用 (void **) 传递 (double ***) 指针是否可以?

Is it OK to pass (double ***) pointers using (void **)?

我使用 gcc 使用 -Wall -Werror 编译下面的代码,它编译得很干净,按预期运行;但是,我只是好奇在 ANSI and/or ISO C 上下文中是否可以传递 (double ***) 指针通过 (void **).

ISO/IEC9899:2017,第 6.6-9 节说:

"The array-subscript [] and member-access . and -> operators, the address & and indirection * unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators."

关于这个建议,函数allocateMatrix实际上应该只是分配内存和return相应的地址;所以,请忽略分配值的内部循环,它仅用于测试目的。

void allocateMatrix(int n, void **a) {
    int i = 0, j = 0;
    double **pTmp = calloc(n, sizeof(double *));

    for (i = 0; i < n; i++) {
        pTmp[i] = malloc(n * sizeof(double));

        // following loop is inserted to make sure code runs as expected
        // this does not exists in real code
        for (j = 0; j < n; j++) {
            pTmp[i][j] = (double)(i + 1) + (double)(j + 1) / 10.0f;
        }
    }

    *a = pTmp;
    return;
}

int main(int argc, char const *argv[]) {
    int i = 0, j = 0;
    int n = 5;
    double **a = NULL;

    // "a" is a (double **) pointer; so, "&a" is now a (double ***) pointer
    allocateMatrix(n, (void **)&a);

    // testing...
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("%6.2lf", a[i][j]);
        }

        printf("\n");
    }

    return 0;
}

C 标准允许在 void * 之间进行转换,但是对于 void **

not 存在 lattitute

将函数参数更改为 void * 并适当地转换它,它将起作用。

void allocateMatrix(int n, void *a) {
    ...
    *(double ***)a = pTmp;
}

并更改从函数调用中删除强制转换:

allocateMatrix(n, &a);