Home > Enterprise >  Array/table declaration in C with variable lengths in element entries
Array/table declaration in C with variable lengths in element entries

Time:01-01

I need to define a table that contain some values of variable lengths. I preferably want to declare it in one go since it's related to constants that will never change. I am checking if I can avoid a dynamic solution i.e. using malloc and set it up in code.

The code below will only serve as pseudo-code of what I want to achieve. It does not work. i.e.

typedef struct myelems {
  char* name;
  int count1;
  int** values1;
  int count2;
  int** values2;
} myelems;

myelems arr[] = {
  {"a", 3, {1, 2, 3}, 1, {42} },
  {"b", 2, {123, 321},  3, {99, 88, 77} },
   // other elements here. . .
  {"x", 0, NULL,            0 , NULL}
};

In this example "a" will contain 3 entries in values1 and 1 entry in values2 such that

arr[0].values1[0] = 1
arr[0].values1[1] = 2
arr[0].values1[2] = 3
arr[0].values2[0] = 42

"b" will contain 2 entries in values1 and 3 in values2 such that

arr[1].values1[0] = 123
arr[1].values1[1] = 321
arr[1].values2[0] = 99
arr[1].values2[1] = 88
arr[1].values2[2] = 77

and "x" have 0 entries in both values1 and values2

I hope this is not a silly question but I just can't find if it is not supported or if it is... if it is how should I do it?

Thanks for anything!

CodePudding user response:

If compound literals are an option you can:

#include <stdio.h>

typedef struct myelems {
    char* name;
    int count1;
    int* values1;  // Notice a single star
    int count2;
    int* values2;  // Notice a single star
} myelems;


int main(void)
{
    myelems arr[] = {
        {"a", 3, (int[]){1, 2, 3}, 1, (int[]){42}},
        {"b", 2, (int[]){123, 321}, 3, (int[]){99, 88, 77}},
        // other elements here. . .
        {"x", 0, NULL, 0 , NULL}
    };
}

Your approach seems a bit dangerous (prone to errors) because you need to hardcode the number of elements of the array in count1 and count2. Let the compiler count for you, with a little help of the preprocessor:

#define MAKE_INTS(...) \
    sizeof((int[]){__VA_ARGS__}) / sizeof(int), (int[]){__VA_ARGS__}

int main(void)
{
    myelems arr[] = {
        {"a", MAKE_INTS(1, 2, 3), MAKE_INTS(42)},
        {"b", MAKE_INTS(123, 321), MAKE_INTS(99, 88, 77)},
        // other elements here. . .
        {"x", 0, NULL, 0 , NULL}
    };
}

MAKE_INTS(1, 2, 3) expands to 3, (int[]){1, 2, 3}.

  • Related