C语言中extern用法详解

来源:互联网 发布:小智淘宝店网址多少 编辑:程序博客网 时间:2024/05/18 21:40

本文基于VC6.0 编译器

首先文档结构如下:
myextern.h和myextern.c中定义extern函数
main.c中定义main方法,调用extern函数

1.第一个尝试:
  myextern.h: void print();
  myextern.c: void print(){..}
  main.c: extern void print(); 并且main(){print()};成功,警告错误均无
  说明extern的作用是,声明本模块中的print()是来自其他模块(myextern.c)的

2.第二个尝试:
  myextern.h: extern void print();
  myextern.c: print(){..}
  main.c: extern void print();并且main(){print()}也没问题,警告错误均无
3.第三个尝试:
  myextern.h: extern void print();
  myextern.c: print(){..}
  main.c: void print();并且main(){print()}也没问题,警告错误均无
4.第四个尝试:
  myextern.h: void print();
  myextern.c: print(){..}
  main.c: void print();并且main(){print()}, 也没问题,警告错误均无

5.第五个尝试:
  myextern.h: void print();
  myextern.c: print(){..}
  main.c: 不声明print(),直接main(){print()},编译时无错误问题,但是有警告:'print' undefined; assuming extern returning int。但是链接时正确,无错误也无警告,另外可以看出,编译器是默认assume它是extern的,这也是接下来6,7两个尝试证明的东西:

6.第六个尝试:
  myextern.h: extern void print();
  myextern.c: print(){..}
  main.c: extern print();并且再次实现print(){..}然后main(){print()},编译时错误:print()重定义了

7.第七个尝试:
  myextern.h: void print();
  myextern.c: print(){..}
  main.c: print();并且再次实现print(){..}然后main(){print()},编译时错误:print()重定义了   

由上述尝试,可以得出结论:无论你有没有声明extern, 当你没有使用static的时候,编译器默认所有模块声明的函数都是extern的,在整个工程命名空间里面,函数是不能重定义的,但是可以重复声明,即:在同一命名空间里,只能有一个函数的实现,比如:你可以:a.h: extern void f();  b.h: extern void f();  c.h: extern void f();  d.h:void f(); 但是,在a.c, b.c, c.c, d.c 中,你只能有一个函数实现,不然,不管过不过的到编译这关,链接的时候肯定会报错,因为你redefinition了~~。
另外注意,不要企图用static void f();声明来区分命名空间,static不能分割可见域,static的作用在于它可以分割作用域,即,其他模块不能使用到static void f();但是,其他模块对于static void f()是可见的,在它们内部,可以声明void f(),但是不能重新对f()进行实现。

发现vc的一个bug:
a.c:
void print()
{
  printf("myextern printf \n");
}
main.c:
void print()
{
printf("this main's print\n");
}

void main()
{
 print();
}

结果是:函数执行的结果很随机:有时候是myextern printf, 有时候是this main's print, 有时候链接出错。 很奇怪,不知道是VC的bug,还是有理解问题

0 0