我有两个共享全局变量的文件。
在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 b
和static 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编译器。
答案 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说明符b
,static
的第一个声明将标识符声明为具有内部链接。带有存储类说明符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
,相同的标识符被声明为具有内部链接