21

In C, I have defined the struct seen below, and would like to initialize it inline. Neither the fields inside the struct, nor the array foos will change after initialization. The code in the first block works fine.

struct Foo {
  int bar;
  int *some_array;
};

typedef struct Foo Foo;

int tmp[] = {11, 22, 33};
struct Foo foos[] = { {123, tmp} };

However, I don't really need the tmp field. In fact, it will just clutter my code (this example is somewhat simplified). So, instead I'd like to declare the values of some_array inside the declaration for foos. I cannot get the right syntax, though. Maybe the field some_array should be defined differently?

int tmp[] = {11, 22, 33};
struct Foo foos[] = {
  {123, tmp},                    // works
  {222, {11, 22, 33}},           // doesn't compile
  {222, new int[]{11, 22, 33}},  // doesn't compile
  {222, (int*){11, 22, 33}},     // doesn't compile
  {222, (int[]){11, 22, 33}},    // compiles, wrong values in array
};
Rodrigo de Azevedo
  • 1,097
  • 9
  • 17
Bob
  • 221
  • 1
  • 2
  • 4

3 Answers3

32

First, there are 2 ways:

  • You know that array's size
  • You don't know that size.

In the first case it is a static programming problem, and it is not complicated:

#define Array_Size 3

struct Foo {
    int bar;
    int some_array[Array_Size];
};

You can use this syntax to fill the array:

struct Foo foo;
foo.some_array[0] = 12;
foo.some_array[1] = 23;
foo.some_array[2] = 46;

When you dont know the array's size, it is a dynamic programming issue. You have to ask the size.

struct Foo {

   int bar;
   int array_size;
   int* some_array;
};


struct Foo foo;
printf("What's the array's size? ");
scanf("%d", &foo.array_size);
//then you have to allocate memory for that, using <stdlib.h>

foo.some_array = (int*)malloc(sizeof(int) * foo.array_size);
//now you can fill the array with the same syntax as before.
//when you no longer need to use the array you have to free the 
//allocated memory block.

free( foo.some_array );
foo.some_array = 0;     //optional

Second, typedef is useful, so the when you write this:

typedef struct Foo {
   ...
} Foo;

it means you replace the "struct Foo" words with this: "Foo". So the syntax will be this:

Foo foo;   //instead of "struct Foo foo;

Cheers.

Bertie92
  • 697
  • 1
  • 9
  • 17
  • The dynamic array is described quite well in GCC docs of one of their extensions: [arrays of length zero](https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html). You can declare an array of length zero as the last member of a struct and place the struct right before the actual array contents in memory. Note that it’s just an extension and standard ways to achieve the same are described there, too. – Palec Mar 15 '15 at 15:12
17
int *some_array;

Here, some_array is actually a pointer, not an array. You can define it like this:

struct Foo {
  int bar;
  int some_array[3];
};

One more thing, the whole point of typedef struct Foo Foo; is to use Foo instead of struct Foo. And you can use typedef like this:

typedef struct Foo {
  int bar;
  int some_array[3];
} Foo;
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 1
    Also, you mention "The fields inside the struct, nor the array foos will change after initialization" then you can prefix their definitions with the "const" prefix. e.g. `const int some_array[3];`. This will allow assignment but not modification. – kfsone Jun 22 '13 at 18:43
  • 1
    @kfsone ITYM it will allow initialization but not assignment or modification – M.M Oct 20 '15 at 21:00
2

My answer is for the following code section:-

int tmp[] = {11, 22, 33};
struct Foo foos[] = {
  {123, tmp},   // works
  {222, {11, 22, 33}},  // doesn't compile
  {222, new int[]{11, 22, 33}},  // doesn't compile
  {222, (int*){11, 22, 33}},  // doesn't compile
  {222, (int[]){11, 22, 33}},  // compiles, wrong values in array
};

All the above compilation issues is due to it not being compatible with the ANSI standards, the aggregate 'foos' is having subaggregates some of which are bracketed while others are not. So if you remove the internal brackets to represent the array 'tmp' it would compile without fail. For eg.

struct Foo foos[] = {
  {123, tmp},   // works
  {222,  11,22,33 },  // would compile perfectly.
}
smitha
  • 21
  • 1