08 Aug, 2011, arholly wrote in the 1st comment:
Votes: 0
Hello:
I'm getting an excessive elements in array initializer error and I'm having problems finding the error (might be sleepiness). Can anyone help please?

{ "conjuration", { 5, 5, -1, -1 },
{ "continual light", "create food", "create rose", "create spring", "create water",
"cure blindness", "cure critical", "cure disease", "cure light", "cure poison",
"cure serious", "gate", "heal", "mass healing", "nexus",
"portal", "summon", "teleport", "word of recall" }
},


The exact error message is:
const.c:1772: warning: excess elements in array initializer
const.c:1772: warning: (near initialization for group_table[11].spells)


And what exactly does that error message mean?

Thank you,
Arholly
08 Aug, 2011, David Haley wrote in the 2nd comment:
Votes: 0
It means pretty much what it says - you have an array of size x, but are trying to initialize it with more than x elements. It might not be that exact entry, it could be the previous or next one too.
08 Aug, 2011, Kaz wrote in the 3rd comment:
Votes: 0
To add to David's fine explanation, I would like to provide a complete program whose sole purpose is to produce that same warning (which it does). Hopefully, this will help you grok the message:

int f[2] = { 1, 2, 3 };

int main(){}
08 Aug, 2011, plamzi wrote in the 4th comment:
Votes: 0
It's easy to forget that in C "int f[2]" means an array of two elements, f[0] and f[1].
08 Aug, 2011, oenone wrote in the 5th comment:
Votes: 0
plamzi said:
It's easy to forget that in C "int f[2]" means an array of two elements, f[0] and f[1].


It would be illogical to assume that there were more than two elements.. regardless of language.
08 Aug, 2011, arholly wrote in the 6th comment:
Votes: 0
Thanks. My MAX_IN_GROUP size was too small. Thanks for the help. Adjusted it upward and now it compiles fine.
08 Aug, 2011, Runter wrote in the 7th comment:
Votes: 0
oenone said:
plamzi said:
It's easy to forget that in C "int f[2]" means an array of two elements, f[0] and f[1].


It would be illogical to assume that there were more than two elements.. regardless of language.


wrt to the person asking he question here, he's probably dealing with a constant for the array size that he has never set. The array might have even let him add more to it (if the constant was a few too big already) without him even realizing he had to set the size somewhere. So it's not really surprising or at all like the f[2] example, as far as it being a stupid mistake goes, anyways. :p
08 Aug, 2011, plamzi wrote in the 8th comment:
Votes: 0
oenone said:
plamzi said:
It's easy to forget that in C "int f[2]" means an array of two elements, f[0] and f[1].


It would be illogical to assume that there were more than two elements.. regardless of language.


If you dabble in C for many years, it would be natural to forget that this is just a syntactical idiosyncrasy. Nothing in the syntax itself makes it clear that f[2] (or even f[MAX_NUM]) is not a valid member of the array. To me, f[2] could just as easily mean f[0], f[1], f[2] and you just have to learn that it doesn't. But then again, I often spread bread on my jam, so it could be just me.
09 Aug, 2011, oenone wrote in the 9th comment:
Votes: 0
plamzi said:
oenone said:
plamzi said:
It's easy to forget that in C "int f[2]" means an array of two elements, f[0] and f[1].


It would be illogical to assume that there were more than two elements.. regardless of language.


If you dabble in C for many years, it would be natural to forget that this is just a syntactical idiosyncrasy. Nothing in the syntax itself makes it clear that f[2] (or even f[MAX_NUM]) is not a valid member of the array. To me, f[2] could just as easily mean f[0], f[1], f[2] and you just have to learn that it doesn't. But then again, I often spread bread on my jam, so it could be just me.


Well, I would always assume a length of 2. If the range is 0..1 or 1..2 is a different matter.
09 Aug, 2011, Kaz wrote in the 10th comment:
Votes: 0
I was trying to demonstrate an array that obviously had more elements than were specified, but … oh well. Drift happens.
09 Aug, 2011, Rarva.Riendf wrote in the 11th comment:
Votes: 0
I suggest to set the value to the exact needed number so you can use it in for loop instead of doing a while( xx != NULL)
It also makes testing easier as you know that if the value is out of the range you defined then there IS a problem.
Transition is easy as well instead of declaring an array without a number, use the MAX_VALUE.
And since compiler will warn you anyway if your array is out of bound, it is a nobrainer to increase it when needed.
It helps a lot when debugging.
09 Aug, 2011, David Haley wrote in the 12th comment:
Votes: 0
You don't always know how many elements you'll have, and it doesn't always make sense to make your arrays as large as the largest array needs to be.

Really, if you were using a language with reasonable container classes, this would be an easy problem to solve… you don't even really worry about it with more modern languages. (And yes, you have tradeoffs.)
09 Aug, 2011, Vigud wrote in the 13th comment:
Votes: 0
I haven't seen the code, so forgive me this question, but: wouldn't the sizeof operator be a good choice here?
09 Aug, 2011, David Haley wrote in the 14th comment:
Votes: 0
No, it's not the problem here, unfortunately. If it's a fixed size array, then you know the size already. If it's dynamically allocated, sizeof won't help you.
09 Aug, 2011, Vigud wrote in the 15th comment:
Votes: 0
I'm sorry, I don't understand. Things in ROM's const.c are dynamically allocated?
09 Aug, 2011, David Haley wrote in the 16th comment:
Votes: 0
No, they're not. That's why sizeof isn't helpful. You know the size already.
09 Aug, 2011, Vigud wrote in the 17th comment:
Votes: 0
I just looked into the code and understood the problem. You were right about that sizeof can't help here.

But I must disagree on that sizeof isn't helpful for static arrays. It is an option similar to using NULL or "" as a boundary for loops.
09 Aug, 2011, Tyche wrote in the 18th comment:
Votes: 0
#include <stdio.h>

int foo[] = {1,2,3,4,5,6,7,8,0};
int bar[3] = {3,2,1};

#define ArraySize(X) (sizeof(X)/sizeof(X[0]))

int main() {
int i;
printf("%d\n",ArraySize(foo));
printf("%d\n",ArraySize(bar));
for (i=0;i<ArraySize(foo);i++)
printf("%d\n",i);
return 0;
}
09 Aug, 2011, Rarva.Riendf wrote in the 19th comment:
Votes: 0
as an example in const.c
const	struct	skill_type	skill_table	[MAX_SKILL]	= {…}
but also
const struct item_type item_table [] =
{
{ ITEM_LIGHT, "light" },
…,
{ 0, NULL }
};


and sometimes a mix of the two…meaning you have no other way than to parse the full list to know the real numer of valid values.
09 Aug, 2011, Tyche wrote in the 20th comment:
Votes: 0
There's always a way as the sizes must be resolved at compile time.
Using the specific example, here's a trimmed down version of the files involved.
/* merc.h */
#include <stdio.h>

typedef int sh_int;

#define MAX_CLASS 4
#define MAX_IN_GROUP 15
#define ArraySize(X) (sizeof(X)/sizeof(X[0]))

struct group_type
{
char * name;
sh_int rating[MAX_CLASS];
char * spells[MAX_IN_GROUP];
};

extern const struct group_type group_table[];
extern const int MAX_GROUP;

/* const.c */
#include "merc.h"

const struct group_type group_table [] =
{
{
"rom basics", { 0, 0, 0, 0 },
{ "scrolls", "staves", "wands", "recall" }
},
{
"mage basics", { 0, -1, -1, -1 },
{ "dagger" }
},
{
"transportation", { 4, 4, 8, 9 },
{ "fly", "gate", "nexus", "pass door", "portal", "summon", "teleport",
"word of recall" }
},
{
"weather", { 4, 4, 8, 8 },
{ "call lightning", "control weather", "faerie fire", "faerie fog",
"lightning bolt" }
}
};

int const MAX_GROUP = ArraySize(group_table);

/* somewhere.c */
#include <stdio.h>
#include "merc.h"

int main() {
int i;
for (i=0;i<MAX_GROUP;i++) {
printf("%d - %s\n",i, group_table[i].name);
}
return 0;
}


$ gcc const.c somewhere.c -o testarray.exe

$ ./testarray.exe
0 - rom basics
1 - mage basics
2 - transportation
3 - weather


Repeat the change as needed for MAX_CLASS, etc.

PS - Actually it's a little trickier than that. You'd have to do some recursive macro foo on const.c to get all the sizes initialized correctly. :-)
0.0/24