c语言sscanf函数的用法是什么
289
2022-12-02
为什么extern使用const修饰的变量会编译不过?
const变量能被其他文件extern引用吗?为什么?
先来看一段代码:
// main.cc#include
编译链接:
$ g++ -o main main.cc const.cc /tmp/ccWHAXxB.o: In function `main':main.cc:(.text+0x6): undefined reference to `const_int'collect2: error: ld returned 1 exit status
我们发现出现了链接问题,说const_int没有定义的引用,但我们确实在说了这么多,举个具体的例子:
#include
这里无链接变量还是比较好区分的,只要不是文件作用域的变量,基本是无链接属性。而文件作用域变量是内部链接还是外部链接呢?只要看前面是否有static修饰即可。当然对于C++,还要看是否有const修饰,后面我们再说。
如何知道某个变量是什么链接属性?
举个例子,在前面的代码中,我们按照C代码进行编译:
$ gcc -c const.c $ nm const.o |grep const_int 0000000000000000 R const_int
nm命令在《linux常用命令-开发调试篇》中略有介绍,它可以用来查看ELF文件的符号信息。
从这里的结果可以看到const_int前面是R修饰的, R:该符号位于只读数据区,READONLY的含义
而该字母大写,其实也是表示它具有外部链接属性。
再看看按照C++代码编译:
$ g++ -c const.c $ nm const.o |grep const_int 0000000000000000 r _ZL9const_int
可以看到,它的修饰符也是r,但是是小写的r,小写字母表示该变量具有内部链接属性。
nm命令非常实用,但本文不是重点。
const关键字
说到const关键字,在《const关键字到底该怎么用》和《C++中的const与C中的const有何差别?》中已经分析过了,这里简单说一下,被const关键字修饰的变量,表明它是只读的,不希望被修改。
extern关键字
extern关键字可以引用外部的定义,想必很多朋友已经很熟悉了,举个例子,如果把最开始的例子中的const关键字去掉,const int const_int = 10;
然后再查看一下:
$ nm const.o |grep const_int 0000000000000000 R const_int
发现没有,它前面的修饰变成大写的R了,所以这个时候,你再编译,就能编译过,而不会报错了,对于C,它本来就是外部链接属性,所以根本不会报错。
extern还有另外一个用法: 《C++是如何调用C接口的》?
解疑
所以,链接报错的通常问题就是找不到定义,原因无非就是:
未定义在其他地方定义了,但是不具备外部链接属性定义了,具备外部链接属性,但是链接顺序有问题
由于在C++中,被const修饰的变量默认为内部链接属性,因为链接会找不到定义。
总结
本文从一个编译问题,引出了很多内容,包括:
作用域 --《全局变量,静态全局变量,局部变量,静态局部变量》const关键字--《const关键字到底该怎么用》extern关键字nm查看符号表
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~