C中静态和外部存储的内存位置class

the memory location of static and extern storage class in C

我有两个共享全局变量的文件。

在main.c

#include<stdio.h>
static int b;
extern int b;
main()
{
extern int a;
printf("a=%d &a:%p\n",a,&a);
printf("b=%d &b:%p\n",b,&b);
fn();
}

在fun.c

#include<stdio.h>
int b=25;
int a=10;
fn()
{
printf("in fna=%d &a:%p\n",a,&a);
printf("in fnb=%d &b:%p\n",b,&b);
}

如果我编译这两个文件。我没有收到任何编译错误。它的 fine.The 输出是

a=10 &a:0x804a018 b=0 &b:0x804a024 in fna=10 &a:0x804a018 in fnb=25 &b:0x804a014

但是,在 main.c 中,如果我像这样更改行 extern int bstatic int b

#include<stdio.h>
extern int b;
static int b;
main()
{
extern int a;
printf("a=%d &a:%p\n",a,&a);
printf("b=%d &b:%p\n",b,&b);
fn();
}

在编译时,我遇到了这个错误。

main.c:6:12: error: static declaration of ‘b’ follows non-static declaration main.c:5:12: note: previous declaration of ‘b’ was here

这里的问题是存储静态和外部变量的内存。但是我无法得出第二次编译错误的确切原因

注意:我使用的是 gcc 编译器。

C 标准(6.2.2 标识符的链接)中的这两个引用将有助于理解问题。

4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

7 If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

在这个翻译单元中

#include<stdio.h>
static int b;
extern int b;
main()
{
extern int a;
printf("a=%d &a:%p\n",a,&a);
printf("b=%d &b:%p\n",b,&b);
fn();
}

标识符 b 具有内部链接(请阅读第一条引文)。 由于存储类说明符 staticb 的第一个声明将标识符声明为具有内部链接。带有 storage-class 说明符 externb 的第二个声明具有带有存储 [=] 的 b(第一个声明)的先前声明39=] 说明符 static。因此标识符的链接与先前声明的标识符的链接相同。

在这个翻译单元中

#include<stdio.h>
extern int b;
static int b;
main()
{
extern int a;
printf("a=%d &a:%p\n",a,&a);
printf("b=%d &b:%p\n",b,&b);
fn();
} 

标识符 b 被声明为具有外部和内部链接(阅读两个引号)。所以编译器发出消息。

起初标识符 b 被声明为具有外部链接(因为没有事先声明具有给定的链接)然后由于说明符 static 相同的标识符被声明为具有内部链接。