I need help with an initializer issue -- the following code works well:

extern int i1, i2;


typedef struct
{
char ch;
int * * array;
} qq_str;


static int * a[] =
{
&i1,
&i2
};


qq_str qq =
{
'c',
a
};

However, I would like to remove the need to construct the array 'a' and embed the initialization directly into the struct -- the following does not compile but illustrates what I'm attempting to accomplish:

qq_str qq =
{
'c',
&{
&i1,
&i2
}
};

Any ideas out there?

Recommended Answers

All 12 Replies

//definition
#define MAX_INT_ARRAY_POINTER       //coder define pointer array size


//extern variable definitions


extern int i1,i2;


//stucture definitions


typedef struct
{
char ch;
int **array;
}  qq_str;


//then memory reservation


qq_str qq;
static int *a[MAX_INT_ARRAY_POINTER+1];


//then set struct variables


qq->ch = 'c';
qq->array = (int **) a;          // chast because different types (int ** and static int *)
gg->array[0] = (int *) &i1;   // chast because different types (int * and static int *)
gg->array[1] = (int *) &i2;   // chast because different types (int * and static int *)

mean you like this ?

Maca;

While a runtime init would work I need a build-time init. The project target is a small 8 bit processor and I don't need the extra overhead that a runtime init would add.

The first init that I listed in the original post is probably as small an init as I can get; I'm just looking for a method of declaring the struct init that doesn't need the array declared outside of the struct (for doc & readability purposes; there will be approximately 50 such struct declared and the actual usage is for * struct [] rather than * int []).

While a runtime init would work I need a build-time init. The project target is a small 8 bit processor and I don't need the extra overhead that a runtime init would add.

The first init that I listed in the original post is probably as small an init as I can get; I'm just looking for a method of declaring the struct init that doesn't need the array declared outside of the struct (for doc & readability purposes; there will be approximately 50 such struct declared and the actual usage is for * struct [] rather than * int []).

Do you know the total number of structs at build time? Could you marry them to an enumeration? <like this> Can you then use an array of pointers to ints rather than a pointer to a pointer to an int?

[edit]...to give you something like this instead?

int i1, i2;

typedef struct
{
   char ch;
   int * array[2];
} qq_str;

qq_str qq =
{
   'c',
   { &i1, &i2 },
};

[edit]Okay, here's a better job of contriving a possible example.

/* test.mh */

/* Macro Definition */
#if   defined(GET_ENUM)
#define BIND(obj)  QQ_##obj,

#elif defined(GET_DECLARATION)
#define BIND(obj)  int obj;

#elif defined(GET_INIT)
#define BIND(obj)  &obj,

#else
#define BIND(code,desc)
#endif

/* Macro Binding */
BIND(i1)
BIND(i2)
BIND(i3)
BIND(i4)
BIND(i5)

/* Macro Un-Definition */
#undef BIND

#if   defined(GET_ENUM)
#undef        GET_ENUM

#elif defined(GET_DECLARATION)
#undef        GET_DECLARATION

#endif
#include <stdio.h>

enum eType
{
   #define GET_ENUM
   #include "test.mh"
   QQ_TOTAL
};

typedef struct
{
   char ch;
   int * array [ QQ_TOTAL ];
} qq_str;

#define GET_DECLARATION
#include "test.mh"

qq_str qq =
{
   'c',
   {
      #define GET_INIT
      #include "test.mh"
   },
};

int main ( void )
{
   int i;
   i1 = 1;
   i2 = 3;
   i3 = 6;
   i4 = 42;
   i5 = -7;
   for (i = 0; i < QQ_TOTAL; ++i)
   {
      printf("*qq.array[i] = %d\n", *qq.array[i]);
   }
   return 0;
}

/* my output
*qq.array[i] = 1
*qq.array[i] = 3
*qq.array[i] = 6
*qq.array[i] = 42
*qq.array[i] = -7
*/

I need to leave the number of ints in any one of these open -- that's why I'm using a pointer to an array of ints. Still need a build-time init rather than a run-time init (this will be compiled into CODE space at build-time).

So the array has a startup initialization, but the array can then grow/shrink at runtime?

Actually it could but in this usage both the array and the pointer to it are 'const'.

The reason that I need to use a pointer to an array in the struct is because there are approx 50 of these things in the project and the size of the array for each is different.

Actually it could but in this usage both the array and the pointer to it are 'const'.

The reason that I need to use a pointer to an array in the struct is because there are approx 50 of these things in the project and the size of the array for each is different.

I'm sorry that I'm slow to follow this, but "the size of the array for each" -- for each what? Maybe it the "pointer to an array in the struct" that's throwing me -- a pointer to a pointer is not the same as a pointer to an array.

[Light bulb?]There are 50 qq_str's each with a different initialization?

The number of ints in each arrray is different for each instance of qq_str; and yes, there are approx 50 of these that each have their own init. The actual usage for this is a double linked list in a menuing setup -- the array is actually the array of child menus associated with the current menu.

Okay. I understand much better now.

I think your original approach may be about as good as you can do without having 50+ distinct structure types used with the thingy I posted.

You mention a need to put this in the CODE section: you are really using const in the declaration, right? Like this?

extern int i1, i2;

typedef struct
{
   char ch;
   const int *const *const array;
} qq_str;

static const int *const a[] =
{
   &i1,
   &i2
};

const qq_str qq =
{
   'c',
   a
};

Then there is no initialization, right?

[EDIT]Dangit. What is the target platform?

Yep, they're declared as 'const' -- they additionally have the extension 'code' used to force loading into program ROM. The target for this is an 8051 derivative.

And you were correct above; I got myself confused reading through this stuff. The actual thingie loaded into the struct is a 'pointer to an array of pointers to int'.

The target for this is an 8051 derivative.

Fun! Keil compiler?

Yep, good old Keil 'C'.

I think I'll just stay with my original method -- I was just looking for something that would make the source a little more readible.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.