initializing an integer array

B

Bill Pursell

I've found myself wanting to do this:

int *x = {1,2,3,4,5};

Obviously, I can't do that. I can certainly non-portably
hack it like int *x = (int *)"\x01\x00\x00\x00\x02\x00...",
but that's the worst idea since W's last one.
Or I can do:
int a[] = {1,2,3,4,5};
int *x=a;
but this is not ideal for the reasons given below.

Is there a way to accomplish the above initialization?
My motivation is the following:

struct args {
int *x;
...
};

#define DEFAULT_ARGS (struct args) {\
.x = DEFAULT_INT_ARRAY;\
...
}

If I can make the assignment happen, then modifying
the defaults is contained in the definition of the DEFAULT_ARGS
macro, but if I can't assign in this way, then DEFAULT_INT_ARRAY
needs to be defined outside of that definition. Granted, it
can be in the immediately preceding line, but it would
be really nice if I could keep it local.

Any thoughts?
 
S

spibou

Bill said:
I've found myself wanting to do this:

int *x = {1,2,3,4,5};

Obviously, I can't do that. I can certainly non-portably
hack it like int *x = (int *)"\x01\x00\x00\x00\x02\x00...",
but that's the worst idea since W's last one.
Or I can do:
int a[] = {1,2,3,4,5};
int *x=a;
but this is not ideal for the reasons given below.

Is there a way to accomplish the above initialization?
My motivation is the following:

struct args {
int *x;
...
};

#define DEFAULT_ARGS (struct args) {\
.x = DEFAULT_INT_ARRAY;\
...
}

If I can make the assignment happen, then modifying
the defaults is contained in the definition of the DEFAULT_ARGS
macro, but if I can't assign in this way, then DEFAULT_INT_ARRAY
needs to be defined outside of that definition. Granted, it
can be in the immediately preceding line, but it would
be really nice if I could keep it local.

Any thoughts?

My first thought is that #define DEFAULT_ARGS (struct args)
defines a "constant" macro and I don't think that this is what you
want. If on the other hand you don't leave a space between
DEFAULT_ARGS and the opening parenthesis then you will get
a syntax error.

Actually come to think of it I don't know what you want. Can you
write what you would want the macro to expand to ?

Spiros Bousbouras
 
G

Guest

Bill said:
I've found myself wanting to do this:

int *x = {1,2,3,4,5};
[...]
Any thoughts?

Since you appear to use C99, you can do

int *x = (int []) { 1, 2, 3, 4, 5 };

However, keep in mind that if you do this in a function, the array is
auto-allocated, and dies when you leave the block. Because of that, you
also can't use it to initialise "static" variables in functions.
 
B

Bill Pursell

Bill said:
I've found myself wanting to do this:

int *x = {1,2,3,4,5};

Obviously, I can't do that. I can certainly non-portably
hack it like int *x = (int *)"\x01\x00\x00\x00\x02\x00...",
but that's the worst idea since W's last one.
Or I can do:
int a[] = {1,2,3,4,5};
int *x=a;
but this is not ideal for the reasons given below.

Is there a way to accomplish the above initialization?
My motivation is the following:

struct args {
int *x;
...
};

#define DEFAULT_ARGS (struct args) {\
.x = DEFAULT_INT_ARRAY;\
...
}

If I can make the assignment happen, then modifying
the defaults is contained in the definition of the DEFAULT_ARGS
macro, but if I can't assign in this way, then DEFAULT_INT_ARRAY
needs to be defined outside of that definition. Granted, it
can be in the immediately preceding line, but it would
be really nice if I could keep it local.

Any thoughts?

My first thought is that #define DEFAULT_ARGS (struct args)
defines a "constant" macro and I don't think that this is what you
want. If on the other hand you don't leave a space between
DEFAULT_ARGS and the opening parenthesis then you will get
a syntax error.

Actually come to think of it I don't know what you want. Can you
write what you would want the macro to expand to ?

Let me give an example of code that is not what I want.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DEFAULT_ARRAY {1,2,3,4,5,0}
#define DEFAULT_ARGS (struct args ) { \
.c = "default string",\
.x = NULL \
}

struct args {
const char *c;
int *x;
};

/*
* Return an array as described by the string
* This stub simply returns the 9 long array
* {1,2,3,4,5,6,7,8,0}
*/
int *
make_array(const char *a)
{
int *ret;
int i;
if ( (ret = malloc(9 * sizeof *ret)) == NULL)
abort();
for (i=0; i<8; i++)
ret = i+1;
ret[8] = 0;
return ret;
}


/*
* Parse the command line args. We establish default
* values, and change as necessary. The ugliness
* in the assymetric treatment of a->x vs. a->c
* is undesired.
*/
void
parse_args(struct args *a, int argc, char *const*argv)
{
int tmp_array[] = DEFAULT_ARRAY;

*a = DEFAULT_ARGS;

if ( argc > 1)
a->x = make_array(argv[1]);
else {
a->x = malloc(sizeof tmp_array);
if (a->x == NULL)
abort();
memcpy(a->x, tmp_array, sizeof tmp_array);
}

if (argc > 2)
a->c = argv[2];
}

int
main(int argc, char **argv)
{
struct args a;
int *t;
parse_args(&a, argc, argv);
printf("array is: {");
for (t=a.x; *t; t++)
printf("%s %d", t==a.x?"":",", *t);
puts("}");
return EXIT_SUCCESS;
}


In this example, I have a structure that wants to be assigned
default values. Assigning values to the char * is easy and
relatively clean. Assigning values to the int * is ugly. I'm
trying to find a more aesthetically appealing way to
accomplish this. I don't know what I want...I'm fishing
for ideas.
 

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,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top