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 } }
};
  • 1
    No, it is not possible. As it is not const you might consider setting the value in the loop runtime – 0___________ Feb 01 '23 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. – Barmar Feb 01 '23 at 22:20
  • 1
    If you don't want so much repetition, you can use a macro for all the identical parts. – Barmar Feb 01 '23 at 22:22
  • Thanks. I suspected this is not possible, but it's good to get a confirmation. – k8AspvNUfYhkvpT9EX5YCSzoLouT0 Feb 01 '23 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](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) 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?](https://stackoverflow.com/q/1449181) – Jonathan Leffler Feb 01 '23 at 22:41
  • There are preprocessing macro libraries which deal with the messy details of doing simple iterations at compile-time. See, for example, Boostpp or Jens Gustedt's P99. My advice is to avoid looking at the implementation details. Just use them. – rici Feb 01 '23 at 22:43
  • I presume you're aware that the range notation `{ [0 ... MAX_OPERATIONS-1] = { … } }` in initializers is specific to GCC (and Clang emulating GCC). That may not be a big concern, but you should be aware that it is not wholly portable. – Jonathan Leffler Feb 01 '23 at 22:58

1 Answers1

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

0___________
  • 60,014
  • 4
  • 34
  • 74