'Too many initialisers'

B

BartC

I get the error 'too many initialisers' with this code:

int x;

int main (void) {
int table[]=
{0,
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x)
};
}

Is there something I'm doing wrong, or another compiler bug to be reported?
(I've already found another - now confirmed - bug with another compiler
earlier today; compiler bugs are supposed to be extremely rare.)

The problem goes away if I have just one less item (the original code has
272), or I replace &x with just x.

Or if I just use a pointer array, which I think I'll use as a workaround.
(This compiler is 64-bits so there would likely be issues with pointer
truncation anyway, although the compiler didn't report this. I haven't used
a pointer array already because the x's are really function pointers in the
original code, and I would have to dig out CDECL to get it right.)

(BTW I'm trying recompiling the same project with 4 or 5 different
compilers. They all report different things as errors! How does anyone
manage to write any sizeable C project and keep multiple compilers happy at
the same time? They all have slightly different link requirements too!)
 
E

Eric Sosman

I get the error 'too many initialisers' with this code:

int x;

int main (void) {
int table[]=
{0,
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x)
};
}

Is there something I'm doing wrong, or another compiler bug to be reported?

The only gotcha I see is the conversion of pointer to `int'.
The result of converting a pointer to an integer is implementation-
defined, and if the result is outside the range of `int' the
behavior is undefined (6.3.2.3p6). So, the situation is a little
bit peculiar: It's implementation-defined, but the implementation
is allowed to "define" it as undefined behavior!

Whether that has anything to do with the compiler's complaint
is anybody's guess. The code is certainly not portable.
(I've already found another - now confirmed - bug with another compiler
earlier today; compiler bugs are supposed to be extremely rare.)

The problem goes away if I have just one less item (the original code has
272), or I replace &x with just x.

Or if I just use a pointer array, which I think I'll use as a workaround.
(This compiler is 64-bits so there would likely be issues with pointer
truncation anyway, although the compiler didn't report this. I haven't used
a pointer array already because the x's are really function pointers in the
original code, and I would have to dig out CDECL to get it right.)

... so it seems quite likely that the converted pointers
are outside the `int' range.
(BTW I'm trying recompiling the same project with 4 or 5 different
compilers. They all report different things as errors! How does anyone
manage to write any sizeable C project and keep multiple compilers happy at
the same time? They all have slightly different link requirements too!)

There's an inherent ambiguity in figuring out "the" error
in a piece of code. Fundamentally, all you can say is that the
code doesn't parse, or violates some constraint or other, or even
exceeds an implementation limit -- but pinpointing "the" point of
departure is fuzzy. Given a faulty chunk of code X, there are many
acceptable variants X1,X2,X3,... at greater or lesser edit distances
from X. An error description like "missing comma" is really a diff
of X and the compiler's choice of some Xn; a different compiler might
choose Xm and report a different diff. Producing an error message
that helps the programmer is at least as much art as science.
 
L

Lew Pitcher

I get the error 'too many initialisers' with this code:

int x;

int main (void) {
int table[]=
{0,
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x)
};
} [snip]
(BTW I'm trying recompiling the same project with 4 or 5 different
compilers. They all report different things as errors! How does anyone
manage to write any sizeable C project and keep multiple compilers happy
at the same time?

One part of the answer it to stick as close as possible to the language
standard, and not use language that results in "implementation-defined"
or "undefined" behaviour.

When you code, for instance, initializers to an integer table where the
values of the initializers are pointers coerced into integer types, you
take the risk of writing (or, if it passes compilation, using) code that
does not do what you think it does. The language standard gives the
compiler the "right" to complain about such code, and (in severe cases)
call such code "an error".


They all have slightly different link requirements too!)

Such is the nature of compilers, and the execution environments in which
they live. I would not, for instance, expect Microsoft Visual C++ (in C
mode) to produce object or binary that can be /directly/ executed on a
Risc-based Linux system, or a S370-based MVS system.
 
K

Keith Thompson

BartC said:
I get the error 'too many initialisers' with this code:

int x;

int main (void) {
int table[]=
{0,
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x)
};
}

I don't. I've tried both gcc and Microsoft's compiler, and your code
compiles without error on both. On one system that has 32-bit int
and 64-bit pointers, I get warnings:

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

The casts are unsafe, and can lose information.

You have more parentheses than you need; each occurence of `((int)&x)`
could be `(int)&x`.

Are you sure that you got that error with the *exact* code you posted?
If not, please pocy-and-paste the actual code that produces the error.
(Telling us what compiler you're using couldn't hurt.)
Is there something I'm doing wrong, or another compiler bug to be reported?
(I've already found another - now confirmed - bug with another compiler
earlier today; compiler bugs are supposed to be extremely rare.)

The problem goes away if I have just one less item (the original code has
272), or I replace &x with just x.

Or if I just use a pointer array, which I think I'll use as a workaround.
(This compiler is 64-bits so there would likely be issues with pointer
truncation anyway, although the compiler didn't report this. I haven't used
a pointer array already because the x's are really function pointers in the
original code, and I would have to dig out CDECL to get it right.)

Then dig out CDECL and get it right. I wouldn't waste time tracking
down errors in code that you already know is wrong.
 
J

Joe Pfeiffer

BartC said:
I get the error 'too many initialisers' with this code:

int x;

int main (void) {
int table[]=
{0,
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x)
};
}

Is there something I'm doing wrong, or another compiler bug to be reported?
(I've already found another - now confirmed - bug with another compiler
earlier today; compiler bugs are supposed to be extremely rare.)

The problem goes away if I have just one less item (the original code has
272), or I replace &x with just x.

Or if I just use a pointer array, which I think I'll use as a workaround.
(This compiler is 64-bits so there would likely be issues with pointer
truncation anyway, although the compiler didn't report this. I haven't used
a pointer array already because the x's are really function pointers in the
original code, and I would have to dig out CDECL to get it right.)

Why is using a pointer array a workaround? You want an array of
pointers to ints; why aren't you simply declaring it that way?
 
B

Ben Bacarisse

BartC said:
int x;

int main (void) {
int table[]=
{0,
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x),
((int)&x)
};
}
(This compiler is 64-bits so there would likely be issues with pointer
truncation anyway, although the compiler didn't report this. I haven't used
a pointer array already because the x's are really function pointers in the
original code, and I would have to dig out CDECL to get it right.)

The simplest way to make function pointer types is to forget about the
pointer -- at least at first. Just find a declaration of a typical
function:

int *some_function(const char *s, int **ipa);

stick "typedef" in front and replace the function name with a name
for the type. You can remove the parameter names if you like, just as
you can in any function declaration:

typedef int *opcode_func(const char *, int **);

This defines a function type. You can make an array of function
pointers using it just like you make an array if integer pointers from
int:

opcode_func *table[] = {...};

This way you finesse the issue of where the *s and ()s go in the full
type. You also get a shorthand for declaring (but not defining)
functions that will go in the table:

opcode_func add_func, sub_func, mul_func;

<snip>
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top