extern关键字的老问题。。

LFYer 2012-11-08 09:30:16

//test1.c
#include<stdio.h>

int a;
int main()
{
printf("%d\n",a);
return 0;
}


//test2.c
int a = 99;

请教各位,为什么输出是99?不是要在test1.c中 “extern int a;” 才是引用test2.c中的a吗?为什么gcc没有提示变量冲突?求解答。。
...全文
622 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2012-11-09
  • 打赏
  • 举报
回复
《程序员的自我修养——链接、装载与库》
weiweishuo 2012-11-09
  • 打赏
  • 举报
回复
引用 10 楼 s_include 的回复:
引用 1 楼 s_include 的回复:默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern 错了,这个 好像是 对 函数 才是 省略 的
恩,引用其它目标文件中的函数不用加extern
weiweishuo 2012-11-09
  • 打赏
  • 举报
回复
引用 7 楼 nwcfafniw 的回复:
引用 1 楼 s_include 的回复:默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern 可是。。如果我单独编译test1.c,则可以通过编译。如果我把int a;改成 extern int a; 则会有错误: test1.c:(.text+0xa): undefined reference t……
这不是编译错误,是链接错误。 楼主能不能把你用的“编译”命令详细贴出来。
weiweishuo 2012-11-09
  • 打赏
  • 举报
回复
未初始化的全局变量,像比test1.c中的‘a’,编译器把它当作弱符号; 已经初始化的全局变量,像比test2.c中的‘a’,编译器把它当作强符号; ld链接test1.o,test2.o时,发现test2.o中的‘a'是强符号,编译器就会用这个’a'覆盖其它弱类型的‘a'。 是链接过程中的强弱符号类型机制,与extern没有关系。
manxiSafe 2012-11-09
  • 打赏
  • 举报
回复
引用 1 楼 s_include 的回复:
默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern
错了,这个 好像是 对 函数 才是 省略 的
LFYer 2012-11-09
  • 打赏
  • 举报
回复
多谢大家,我懂了~结贴~
weiweishuo 2012-11-09
  • 打赏
  • 举报
回复
引用 10 楼 s_include 的回复:
引用 1 楼 s_include 的回复:默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern 错了,这个 好像是 对 函数 才是 省略 的
引用 9 楼 startservice 的回复:
引用 7 楼 nwcfafniw 的回复:引用 1 楼 s_include 的回复:默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern 可是。。如果我单独编译test1.c,则可以通过编译。如果我把int a;改成 extern int a; 则会有错误: test1.c:(.text+0xa): ……
恩,两种都可以,但实质不一样。做下面的测试: a.c ------ #include<stdio.h> int a; void main(){ printf("%d“,a); } ------ gcc -o a a.c 编译成功。 改动一下,把a声明为extern a.c ------ #include<stdio.h> extern int a; void main(){ printf("%d“,a); } ------ gcc -o a a.c 报错:/tmp/ccNWJt2v.o: In function `main': a.c:(.text+0xb): undefined reference to `a' 因为int a声明a是弱类型的符号,即使没有初始化,连接器引用它时也不会报错。 写成“extern int a”,那么a既非弱类型也非强类型,链接器回到其它目标文件找a,找不到,就报错了。
startservice 2012-11-08
  • 打赏
  • 举报
回复
引用 7 楼 nwcfafniw 的回复:
引用 1 楼 s_include 的回复:默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern 可是。。如果我单独编译test1.c,则可以通过编译。如果我把int a;改成 extern int a; 则会有错误: test1.c:(.text+0xa): undefined reference t……
linux 上两种都可以,LZ单独编译test1.cextern int a是不行的
visayafan 2012-11-08
  • 打赏
  • 举报
回复
test1.c
#include <stdio.h>

int a;
int main(int argc, char *argv[])
{
    printf ("%d\n",a);
    return 0;
}
结果0 test2.h
int a=99;
test1.c
#include <stdio.h>
#include "test2.h"

extern int a;
int main(int argc, char *argv[])
{
    printf ("%d\n",a);
    return 0;
}
结果99
LFYer 2012-11-08
  • 打赏
  • 举报
回复
引用 1 楼 s_include 的回复:
默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern
可是。。如果我单独编译test1.c,则可以通过编译。如果我把int a;改成 extern int a; 则会有错误: test1.c:(.text+0xa): undefined reference to `a' 既然extern是默认加上去的,那么为什么前者行后者不行。
wizard_tiger 2012-11-08
  • 打赏
  • 举报
回复
好像extern(外部变量)是默认的,static才是要写出来的吧!
newtee 2012-11-08
  • 打赏
  • 举报
回复
如果一个源程序由若干个源文件组成,在一个源文件中想使用在其他源文件中已经定义的外部变量,则需用extern对该变量做“外部变量”说明
zodiac1111 2012-11-08
  • 打赏
  • 举报
回复
static 关键字可以避免编译器的小(?)聪明. 明确不需要被其他文件extern的全局变量,显式的告诉编译器,表extern我
newtee 2012-11-08
  • 打赏
  • 举报
回复
没见过这种现象
newtee 2012-11-08
  • 打赏
  • 举报
回复
静态变量(static)与全局变量都默认为0
manxiSafe 2012-11-08
  • 打赏
  • 举报
回复
默认都是 有 extern 的 只是没 写出来 int a;// extern int a;省略了extern

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧