Pregunta

I'm experiencing some weird behaviour (well, i guess it's got an explanation) while trying to cross compile some Files from Debian to an arm-linux target, using:

$ arm-linux-gnueabi-gcc --version

$ arm-linux-gnueabi-gcc (Debian 4.3.5-4) 4.3.5

While compiling I get these error messages:

dsblock1.c:167: error: non-static declaration of ‘HaveEventIterated_’ follows static declaration
ss2dym.c:778: error: previous declaration of ‘HaveEventIterated_’ was here

The corresponding Lines are:

ss2dym.c:778 :
extern long HaveEventIterated_;

"redeclaration" dsblock1.c:167:
long HaveEventIterated_=0;

So here's the thing i don't get: according to what i thought i knew, variables first declared extern, are non-statics.

BUT: the "extern" declaration is inside a static function. So my guess is, that this is some kind of inherited behaviour?!

So here are the questions: - can someone explain the background story, IF my guess is correct? - is there an easy way to get around that, e.g. with a tricky compiler-flag that allows nested scope-shifting or some other magic?

I know it would most likely possible to create a header and put all those extern declarations into neutral space, but i've got like hundreds of those errors and several files. And i've seen that this code compiles well using MSVC++ (that has other scope constraints, i know, but i have a lot more problems using arm-g++) so there must be some kind of solution, easier than just rewriting all those parts...

BTW: there is an easy way to change the scope of all those "redeclarations" since i have a macro in front of all of them like:

MY_MACRO long HaveEventIterated_=0;

and atm i compile with -DMY_MACRO=

Soooo anyone? :)

¿Fue útil?

Solución

The extern keyword gives identifiers the same linkage1 as a previous visible declaration, or external linkage if there is no previous visible declaration. (This is a weird quirk of the language, to be sure.)

Thus, the problem is most likely occurring due to a third (or perhaps I should say "first") declaration of HaveEventIterated_, that the compiler is reaching before it reaches line 778 of ss2dym.c. That third (or first) declaration uses the static keyword to give the identifier internal linkage. The second declaration, with extern, then gives the same variable internal linkage, and the third—with no storage-class keyword to specify linkage—gives the variable external linkage, resulting in the error.

Here's a short example that reproduces the issue (in a different gcc, but the same behavior):

$ cat foo2.c
static int var;
extern int var;
int var = 0;
$ gcc -c foo2.c
foo2.c:3: error: non-static declaration of 'var' follows static declaration
foo2.c:2: error: previous declaration of 'var' was here

1Side note: if the previous visible declaration has no linkage, you get external linkage. This only occurs when re-declaring a variable inside a block where the variable outside that block has automatic duration, i.e., is a "local" or "stack" variable inside a function:

void f(void) {
    int v;
    {
        extern int v;

Here there's a previous visible declaration with no linkage, so the innermost v has external linkage. If there is a v with internal linkage in the same translation unit, the effect is undefined. (Of course no one should write code like f() in the first place, anyway :-) )

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top