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

时间:2016-03-17 09:38:54

标签: c static compiler-errors declaration extern

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

在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);
}

如果我编译两个文件。我没有收到任何编译错误。它很好。输出

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编译器。

1 个答案:

答案 0 :(得分:2)

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

  

4对于使用storage-class specifier extern声明的标识符   在该标识符的事先声明的范围内   如果事先声明指定内部或外部,则可见   联系,后来声明中标识符的链接是   与先前声明中指定的联系相同。如果没有事先   声明是可见的,或者如果先前声明指定否   链接,然后标识符有外部链接。

  

7如果在翻译单元中,同时出现两个标识符   内部和外部联系,行为未定义。

在此翻译单元

#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具有内部链接(读取第一个引用)。 由于存储-calss说明符bstatic的第一个声明将标识符声明为具有内部链接。带有存储类说明符extern b 的第二个声明事先声明了b(第一个声明)与存储类说明符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,相同的标识符被声明为具有内部链接