0

Suppose I have the following data structure:

#include <pthread.h>

#define MAX_OPERATIONS 8

typedef enum _dimension_t {
    LENGTH = 0,
    WIDTH  = 1,
    HEIGHT = 2,
    MAX_DIMENS = 3
} dimension_t;

typedef int (*write_fptr_t)(int);
typedef int (*read_fptr_t)(int *);

typedef struct _mydata_t {
    const dimension_t     dimension;
    const unsigned int    operation;
    const pthread_mutex_t lock;
    const write_fptr_t    wr_func_ptr;
    const read_fptr_t     rd_func_ptr;
    int                   x;
    int                   y;
    char                  data[8];
    float                 z;
    double                a;
} mydata_t;

extern int length_wr_fptr(int val);
extern int width_wr_fptr(int val);
extern int height_wr_fptr(int val);

extern int length_rd_fptr(int * val);
extern int width_rd_fptr(int * val);
extern int height_rd_fptr(int * val);

Now I want to initialize an array of mydata_t. I could do:

mydata_t mydata[MAX_DIMENS][MAX_OPERATIONS] = {
  {
    { LENGTH, 0, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },
    { LENGTH, 1, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },
    { LENGTH, 2, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },
    { LENGTH, 3, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },
    { LENGTH, 4, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },
    { LENGTH, 5, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },
    { LENGTH, 6, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },
    { LENGTH, 7, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr }  },
  {
    { WIDTH,  0, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },
    { WIDTH,  1, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },
    { WIDTH,  2, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },
    { WIDTH,  3, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },
    { WIDTH,  4, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },
    { WIDTH,  5, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },
    { WIDTH,  6, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },
    { WIDTH,  7, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr }  },
  {
    { HEIGHT, 0, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr },
    { HEIGHT, 1, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr },
    { HEIGHT, 2, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr },
    { HEIGHT, 3, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr },
    { HEIGHT, 4, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr },
    { HEIGHT, 5, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr },
    { HEIGHT, 6, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr },
    { HEIGHT, 7, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr }  }
};

This works, but is long.

Alternatively, I could do:

mydata_t mydata[MAX_DIMENS][MAX_OPERATIONS] = {
    { [0 ... MAX_OPERATIONS-1] = { LENGTH, 0, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr } },
    { [0 ... MAX_OPERATIONS-1] = { WIDTH,  0, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr  } },
    { [0 ... MAX_OPERATIONS-1] = { HEIGHT, 0, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr } }
};

This is shorter, but the operation field does not get initialized correctly.

Question: is there a way to initialize a member variable to the array index? Something like?

mydata_t mydata[MAX_DIMENS][MAX_OPERATIONS] = {
    { [0 ... MAX_OPERATIONS-1] = { LENGTH, ##INDEX##, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr } },
    { [0 ... MAX_OPERATIONS-1] = { WIDTH,  ##INDEX##, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr  } },
    { [0 ... MAX_OPERATIONS-1] = { HEIGHT, ##INDEX##, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr } }
};
7
  • 1
    No, it is not possible. As it is not const you might consider setting the value in the loop runtime Commented Feb 1, 2023 at 22:20
  • The [start ... end] = syntax can only be used if you're initializing all elements to the same value. I don't see any way to get the index into the initializations. Commented Feb 1, 2023 at 22:20
  • 1
    If you don't want so much repetition, you can use a macro for all the identical parts. Commented Feb 1, 2023 at 22:22
  • Thanks. I suspected this is not possible, but it's good to get a confirmation. Commented Feb 1, 2023 at 22:23
  • Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of C11 §7.1.3 Reserved identifiers says: — All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. See also What does double underscore (__const) mean in C? Commented Feb 1, 2023 at 22:41

1 Answer 1

2

maybe:

#define MINIT(n) [LENGTH][n] = { LENGTH, n, PTHREAD_MUTEX_INITIALIZER, length_wr_fptr, length_rd_fptr },\
                 [WIDTH][n] = { WIDTH,  n, PTHREAD_MUTEX_INITIALIZER, width_wr_fptr,  width_rd_fptr },\
                 [HEIGHT][n] = { HEIGHT, n, PTHREAD_MUTEX_INITIALIZER, height_wr_fptr, height_rd_fptr }\


mydata_t mydata[MAX_DIMENS][MAX_OPERATIONS] =  
     { MINIT(0), MINIT(1), MINIT(2), MINIT(3), 
       MINIT(4), MINIT(5), MINIT(6), MINIT(7)}; 

https://godbolt.org/z/33ehP563W

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.