Initialization Problem

T

Thorsten Schilling

Hello everybody,

I have the following problem. Consider the following structure:

typedef struct{
unsigned int *msk;
unsigned int **ass;
unsigned int n;
}sym;

Now I would like to initialize an array of this "sym"'s at compile
time. Clearly msk should contain a pointer to e.g. {0x1,0x2,0x3} and
ass to something like {{0x1,0x2,0x3},{0x1,0x2,0x3},{0x1,0x2,0x3}}.
Question is now what is the easiest and most readable way to perform
that.

What doesn't work (or it gives me a warning) like
[...]
../testdata.h:5: warning: braces around scalar initializer
.../testdata.h:5: warning: (near initialization for ‘testdata[0].msk’)
.../testdata.h:5: warning: initialization makes pointer from integer
without a cast
.../testdata.h:5: warning: excess elements in scalar initializer
[...]

is:

static sym testdata[1] = {
{{0x1,0x2},{{0x1,0x2},{0x1,0x2}},3}};

Thanks in advance for any help.

Thorsten
 
J

James Kuyper

Thorsten said:
Hello everybody,

I have the following problem. Consider the following structure:

typedef struct{
unsigned int *msk;
unsigned int **ass;
unsigned int n;
}sym;

Now I would like to initialize an array of this "sym"'s at compile
time. Clearly msk should contain a pointer to e.g. {0x1,0x2,0x3} and
ass to something like {{0x1,0x2,0x3},{0x1,0x2,0x3},{0x1,0x2,0x3}}.
Question is now what is the easiest and most readable way to perform
that.

What doesn't work (or it gives me a warning) like
[...]
./testdata.h:5: warning: braces around scalar initializer
../testdata.h:5: warning: (near initialization for ‘testdata[0].msk’)
../testdata.h:5: warning: initialization makes pointer from integer
without a cast
../testdata.h:5: warning: excess elements in scalar initializer
[...]

is:

static sym testdata[1] = {
{{0x1,0x2},{{0x1,0x2},{0x1,0x2}},3}};

Making a one-element array is pointless, just use

static sym testdata = {

Two of the members of your struct are pointers; one of them is a pointer
to a pointer. Your initializers for that struct include not a single
pointer. You should view this as a sign that something is wrong.
Pointers can be subscripted just like arrays (this is because arrays
automatically become pointers when subscripted). This can cause the
misconception that pointers and arrays are more similar than they really
are.

Defining a variable of pointer type only sets aside memory for the
pointer itself; it does not set aside memory to store the object being
pointed at. You have to arrange that separately. Since you want to do
this at compile time, you'll have to use something like the following:

static unsigned int vector = {1, 2};
static unsigned int array = {{1, 2}, {1,2}, {1,2}};
static unsigned int *rows[] = {array, array+1, array+2};
static sym testdata = { vector, rows, 3);
 
T

Thorsten Schilling

Thanks a lot for the answer so far. I know that it is pointless to
have a one-element array, it should become an array (or pointer to the
first of n) of syms afterwards. My specific question is if I can now
somehow "compact" this 4 lines:
static unsigned int vector = {1, 2};
static unsigned int array = {{1, 2}, {1,2}, {1,2}};
static unsigned int *rows[] = {array, array+1, array+2};
static sym testdata = { vector, rows, 3);

in one "line". I will have a lot syms (approx 128) where each will
have approximately 2^7 rows with width 2, which will cause a lot
unnecessary generation of static variables i'll never use. So for
example "static unsigned int vector = {1,2}; causes "vector" to store
the address of the first element. But with which language construct/
feature can i get out of the expression "{1,2}" the address of the
first element without the detour of a variable named vector? Cause I
don't really need it. It is enough if it is stored in the first
element of my sym datatype.

Thanks again,
Thorsten
 
J

James Kuyper

Thorsten said:
Thanks a lot for the answer so far. I know that it is pointless to
have a one-element array, it should become an array (or pointer to the
first of n) of syms afterwards. My specific question is if I can now
somehow "compact" this 4 lines:
static unsigned int vector = {1, 2};
static unsigned int array = {{1, 2}, {1,2}, {1,2}};
static unsigned int *rows[] = {array, array+1, array+2};
static sym testdata = { vector, rows, 3);

in one "line". I will have a lot syms (approx 128) where each will
have approximately 2^7 rows with width 2, which will cause a lot
unnecessary generation of static variables i'll never use. So for
example "static unsigned int vector = {1,2}; causes "vector" to store
the address of the first element. But with which language construct/
feature can i get out of the expression "{1,2}" the address of the
first element without the detour of a variable named vector? Cause I
don't really need it. It is enough if it is stored in the first
element of my sym datatype.

Does testdata.msk always point at the first element of an array of
length 2? Then it would be simpler to make msk be an array of length 2.
Is "ass" always a pointer to an array of n pointers to an array of 2
ints? Then there's no need to declare it as "int **ass". it would be
better to declare it as "int (*ass)[2]".

How big is the ratio between the maximum value of n and the average
value of n? If that ratio is small enough, the simplest solution would
be to declare it as "int ass[MAX_N][2]".

If you can make all three of those changes, your original initialization
would work perfectly.

If you can afford to restrict the portability of your code to those
implementations which support C99 compound literals, you could try the
following approach:

static sym testdata = { (int[]){1,2},
(int*[]){(int[]){1,2}, (int[]){1,2},(int[]){1,2}}, 3};
 
T

Thorsten Schilling

Thorsten said:
Thanks a lot for the answer so far. I know that it is pointless to
have a one-element array, it should become an array (or pointer to the
first of n) of syms afterwards. My specific question is if I can now
somehow "compact" this 4 lines:
static unsigned int vector = {1, 2};
static unsigned int array = {{1, 2}, {1,2}, {1,2}};
static unsigned int *rows[] = {array, array+1, array+2};
static sym testdata = { vector, rows, 3);
in one "line". I will have a lot syms (approx 128) where each will
have approximately 2^7 rows with width 2, which will cause a lot
unnecessary generation of static variables i'll never use. So for
example "static unsigned int vector = {1,2}; causes "vector" to store
the address of the first element. But with which language construct/
feature can i get out of the expression "{1,2}" the address of the
first element without the detour of a variable named vector? Cause I
don't really need it. It is enough if it is stored in the first
element of my sym datatype.

Does testdata.msk always point at the first element of an array of
length 2? Then it would be simpler to make msk be an array of length 2.
Is "ass" always a pointer to an array of n pointers to an array of 2
ints? Then there's no need to declare it as "int **ass". it would be
better to declare it as "int (*ass)[2]".

How big is the ratio between the maximum value of n and the average
value of n? If that ratio is small enough, the simplest solution would
be to declare it as "int ass[MAX_N][2]".

If you can make all three of those changes, your original initialization
would work perfectly.

If you can afford to restrict the portability of your code to those
implementations which support C99 compound literals, you could try the
following approach:

static sym testdata = { (int[]){1,2},
        (int*[]){(int[]){1,2}, (int[]){1,2},(int[]){1,2}}, 3};

Thanks, that works perfectly. And C99 should be ok.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top