2

In my function bodies reduce() and initialize(...) I want to work with the array globalArray as a three-dimensional one, where the dimensions are not known until runtime.

How do I cast the globalArray pointer to a variable-length array (pointer) and use it naturally? I think the typedef approach helps, but I'm still lost. This current version compiles and seemingly works after my tinkering. Are Cast #1 and Cast #2 as clear and safe as can be achieved?

#include <stdlib.h>
#include <stdio.h>

double * globalArray; /* working from a situation where the array is global, declared elsewhere */
int M, N, P; /*array dimensions not known until runtime */

double reduce();
double reduce()
{
    /* Here I want to re-interpret the one-dimensional globalArray into
       a multi-dimensional variable-length array so that compiler takes
       care of the indexing math for me.*/
    typedef double (*arr_t)[N][P];

    const arr_t castArray = (arr_t)globalArray;  /* Cast #1 */

    double sum=0.0;
    for (int i=0; i<M; i++)
        for (int j=0; j<N; j++)
            for (int k=0; k<P; k++)
                sum += castArray[i][j][k];
    return sum;
}

void initialize(int M, int N, int P, double threedimarray[M][N][P])
{
    for (int i=0; i<M; i++)
        for (int j=0; j<N; j++)
            for (int k=0; k<P; k++)
                threedimarray[i][j][k] = (double)(i*N*P + j*P + k);
}

int main(int argc, char **argv)
{
    M = 10; N=1000; P=200;
    globalArray = malloc( M*N*P* sizeof(double) );

    typedef double (*arr_t)[N][P];
    initialize(M, N, P, (arr_t)globalArray); /* Cast #2 */

    double result = reduce();
    printf("Reduced result: %f\n", result );
    return 0;
}

https://ideone.com/5Y8Q64

I'm reworking a small section of a large program. There are clearly better design approaches than program scope array pointers. It is what it is. From a self-documenting point-of-view, it'd be nice if the solution doesn't throw away the fact that we "know" the extent of the leading dimension (M) as well.

The similar SO questions relating to function argument declarations are helpful but I'm not connecting the dots I guess. I decided to ask here hoping the answer will reach more people.

4
  • Did you try: double castArray[M][N][P] = (double[][][])globalArray; ? Commented Sep 26, 2017 at 16:06
  • Well, now I have: error: array has incomplete element type 'double []' Commented Sep 26, 2017 at 16:09
  • You can do it like this, but M, N and P must be const: double(castArray)[2][2][2] = (double()[2][2][2])globalArray; But it is better to access globalArray like this: globalArray[i * M + j * N + k], where 0 <= i < M; 0 <= j < N; 0 <= k < P; Commented Sep 26, 2017 at 16:23
  • 1
    The correct expression would be globalArray[i * N*P + j * P + k] but that's exactly what I am trying to avoid with C99 variable-length arrays functionality. Commented Sep 26, 2017 at 16:53

1 Answer 1

2

Here's one possible casting solution I've arrived at after some tinkering.

typedef double (*arr_t)[N][P];
arr_t castArray = (arr_t)globalArray;

/* Now castArray can be accessed by multi-dimensional index notation */
castArray[i][j][k] = 3.14;

Downsides:

1) Does not self-document known leading dimension length M.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.