Re: Why error "variable previously declared ‘static’ redeclared ‘extern’"?

A A wempwer@gmail.com
Mon Jul 7 15:52:00 GMT 2014


On 7/7/14, Alec Teal <a.teal@warwick.ac.uk> wrote:
> Sorry for the repost, Thunderbird decided (or I have found a keyboard
> shortcut) to remove all your text, so my post had no context!
>
> On 07/07/14 14:04, A A wrote:
>> The following code gives me an error when trying to build with gcc-4.8:
> Good
>>
>> #include<stdio.h>
>> #include<stdlib.h>
>>
>> static int i5 = 30;
> There will be "global" i5 int somewhere in the program's memory BUT
> the linker will not let (as it cannot see) this i5 symbol from any other
> object file.
> That is it has "internal linkage". Yes it says "static" which is an odd
> choice of keyword
> but it does not mean static for all to access, it means internal linkage.
> Read Denis Ritchie's famous book, it talks about symbols and linkage.
>>
>> int main(void)
>> {
>>      int i5 = 12;
>>      printf("i5: %d\n", i5);
>>      {
>>          extern int i5;
> Why did you write this line? What are you trying to do? What this says is
> "make the linkage of i5 external" meaning other objects can have i5
> linked into
> them. BUT you've already said i5 is internal, thus a contradiction.

"you've already said i5 is internal" - what i5 are you talking about
here - the one defined with `static' or the one defined in the first
line of main()? The former has internal linkage but latter has no
linkage if I understand standard correctly:

6.2.2 p. 6:

The following identifiers have no linkage: an identifier declared to
be anything other than an object or a function; an identifier declared
to be a function parameter; a block scope identifier for an object
declared without the storage-class specifier extern.

So I guess you must be talking about i5 defined with `static' outside
main(). But even on page 144 of C standard you mentioned it is legal
to use `extern' to a variable with internal linkage so I don't really
understand your point. Where is the contradiction? If I understand
standard correctly there is no way to use `extern' to refer to a
variable with no linkage. I tried to use `extern' on a variable
defined inside function in this way and both Clang and GCC failed at
linking stage:

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

int main(void)
{
        int a = 10;
        {
                extern int a;
                printf("%d\n", a);
        }
}

As such, `extern' cannot refer to i5 defined inside main() but only to
static i5. After removing a definition of i5 in the first line of
main() this code compiles correctly also in GCC. I think that GCC
could notice that and do the same thing as Clang but it doesn't, for
some reason, probably because this is the way it is designed.

By the way, output of program from my 1st post after compiling it with
Clang is:

i5: 12
i5: 30
i5: 12

And why do I this - after a few years of using C I feel I need to
enhance my knowledge on linkage vs scope vs duration and other
issues. I want to know how C really works, not only write code that
'somehow' works. I picked `static' keyword to study because I know it
has dual meaning in C and I want to understand what it really means. I
write small programs like this to check my understanding of C
standard. I have started reading C standard on my own a weeks ago and
although I slowly dive into strict technical English I realize that I
still don't understand a half of it. In such situations, when you
really want to understand something deeply it makes you frustrated
when two leading compilers give you answers that are mutually
exclusive. You start to wonder - is that you, the way one compiler
works and another doesn't, compiler bug, obsolete version of standard
you are reading (maybe C11 feature?), undefined or implementation
defined behavior. You are lost and you ask question on GCC mailing
group. That's it.



More information about the Gcc-help mailing list