How to build a char[][] in k&r dialect.

M

Matt

I'm writing code for the apple 2 which requires that I use the pre-ansi
k&r C dialect. This is apparently not allowed:
char *choices[] = {
"foo",
"bar",
"more",
"stuff"
};

Aztec C65 v3.2a 6-30-86
char *choices[] = {
^
ERROR 38: no auto. aggregate initialization allowed

So I did this:
char *ch0 = "foo";
char *ch1 = "bar";
....

char **choices;

choices[0] = ch0;
choices[1] = ch1;
....

But surely this can't be the way people used to do things? What if it
was choices[100][] instead of choices[4][]? Seems tedious.

Matt.
 
E

Eric Sosman

I'm writing code for the apple 2 which requires that I use the pre-ansi
k&r C dialect. This is apparently not allowed:
char *choices[] = {
"foo",
"bar",
"more",
"stuff"
};

Aztec C65 v3.2a 6-30-86
char *choices[] = {
^
ERROR 38: no auto. aggregate initialization allowed
[...]

I suspect that the problem isn't "aggregate initialization,"
but "auto aggregate initialization." To test this, try writing
`static char *choices[] = ...' instead (or move the whole thing
to file scope, outside a function), and see what happens.

If `choices' gets modified in the course of the function and
must be re-initialized next time around, `static' won't work.
Then you'd have to do something like

static char *init[] = { "foo", ... };
char *choices[sizeof init / sizeof init[0]);
memcpy(choices, init, sizeof choices);

However, I'm really only guessing. The principal motivation
for the ANSI Standard was that there was no single, well-understood
C dialect. Compilers had different ideas about what was and wasn't
allowed, and different ideas about precisely what allowed things
meant. One area where they differed was in how much run-time
code they'd generate to initialize `auto' variables each time a
block was entered, which translated into different restrictions
on what kinds of initializers were permitted, and if you make the
array non-`auto' you may well escape those restrictions.
 
G

glen herrmannsfeldt

Matt said:
I'm writing code for the apple 2 which requires that I use the pre-ansi
k&r C dialect. This is apparently not allowed:
char *choices[] = {
"foo",
"bar",
"more",
"stuff"
};
Aztec C65 v3.2a 6-30-86
char *choices[] = { ^
ERROR 38: no auto. aggregate initialization allowed

Make it static, and it should work.

I had many of those in the pre-ANSI days, and still often like
to make them static.

Pre-ANSI, you could initialize scalars (static or auto) or arrays
(static only), but not auto arrays. Makes sense to me.

-- glen
 
M

Matt

I suspect that the problem isn't "aggregate initialization,"
but "auto aggregate initialization." To test this, try writing
`static char *choices[] = ...' instead

This works.

(or move the whole thing
to file scope, outside a function), and see what happens.

This also works.
If `choices' gets modified in the course of the function and
must be re-initialized next time around, `static' won't work.
Then you'd have to do something like

static char *init[] = { "foo", ... };
char *choices[sizeof init / sizeof init[0]);
memcpy(choices, init, sizeof choices);

Thanks for the example.
However, I'm really only guessing. The principal motivation
for the ANSI Standard was that there was no single, well-understood
C dialect. Compilers had different ideas about what was and wasn't
allowed, and different ideas about precisely what allowed things
meant. One area where they differed was in how much run-time
code they'd generate to initialize `auto' variables each time a
block was entered, which translated into different restrictions
on what kinds of initializers were permitted, and if you make the
array non-`auto' you may well escape those restrictions.

Thanks for this explanation. It fits with other changes I'm having to
make to make my ansi code work with the old compiler. Retrocomputing is
giving me new respect for ANSI and the GNU toolchain!

Matt.
 
E

Eric Sosman

[...]
If `choices' gets modified in the course of the function and
must be re-initialized next time around, `static' won't work.
Then you'd have to do something like

static char *init[] = { "foo", ... };
char *choices[sizeof init / sizeof init[0]);
memcpy(choices, init, sizeof choices);

Thanks for the example.

You're welcome -- but fix my tyop!
 
M

Matt

Make it static, and it should work.

Yes it does.

I had many of those in the pre-ANSI days, and still often like
to make them static.

Pre-ANSI, you could initialize scalars (static or auto) or arrays
(static only), but not auto arrays. Makes sense to me.

Yes it makes sense. I guess if like me you only have experience with
ansi C you can end up taking a bunch of stuff for granted.

Thanks Eric, Glen.

Matt.
 
G

glen herrmannsfeldt

(snip, I wrote)
Yes it makes sense. I guess if like me you only have experience with
ansi C you can end up taking a bunch of stuff for granted.

In the case of an initialized auto variable, it takes enough space
to store both the initial value and the current (variable) value.

In the case of static, most systems initialize the value while
loading the program into memory, so no waste. In the early days
of C, computers were smaller than today.

For some systems, though, if you static initialize a large array
with all elements the same value, all those go into the executable
file. Some compress out zeros, but leave other constants in the file.

-- glen
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top