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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 7 July 2014 16:51, A A <wempwer@xxxxxxxxx> wrote:
> On 7/7/14, Alec Teal <a.teal@xxxxxxxxxxxxx> 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.

Paragraph 4 says the "extern int i5" has external linkage, because the
prior declaration (the first one in main) has no linkage. So you've
declared i5 to have both internal linkage (the first declaration of
i5) and external linkage (the third declaration of i5) and paragraph 7
says that is undefined.



> 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.

But you've re-declared it with different linkage.

> After removing a definition of i5 in the first line of
> main() this code compiles correctly also in GCC.

Because by 6.2.2 p4 the prior declaration is the one at file scope,
and the re-declaration has the same linkage.  The difference is which
prior declaration is visible.


> 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.

You're saying GCC should have particular behaviour for something which
is undefined behaviour. That's not how undefined behaviour works.

You should fix your program.

> 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.

And the answer to your question is that the standard says it's
undefined behaviour.




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux