【extern const 的用法】问题 一
1.cpp
extern const int i;
//const int i = 1;
const int i = 1;
//extern const int i;
int main(){return 0;
}
2.cpp
extern const int i = 2;
为什么这样不能通过链接,而如果按注释里的顺序就能通过链接,这个怎么解释呢?
问题二
在C++中,定义一个全局的符号常量。在a.cpp中定义extern const double pi=3.14;
b.pp中extern const double pi;
可以通过编译运行。在a.cpp中定义const double pi=3.14;
b.pp中extern const double pi;
编译失败。
这两个问题有几个概念需要搞清楚。
1. const对象是文件局部变量。意味着,其他文件将不能Link到本文件的Const变量。
2. 如果在const前面加extern,意味着这个const对象可以被其他文件link到。
3. 在通过extern const变量进行获取声明而非初始化的时候,编译器会首先选择寻找这句extern之前有没有该对象的初始化声明。这是容易理解的,因为const的作用域本来就是文件作用域。如果在自己extern之前找不到(编译器是自上而下编译代码,它并不知道自己之后是什么),那么去外部看有没有其他使用extern方式初始化这个对象的地方。如果有,编译通过。如果没有会报link错误。
问题一 分析:
通过以上三点。我们来对你的代码进行解读。你在1.cpp中如果先extern const int i,那么根据上述第三点,它先找自己之前有没有对i的初始化。很明显没有能够找到。于是去文件外部寻找link的place holder,结果发现在2.cpp中果然有这么一个定义。于是一个const i已经被找到并且已经被初始化。而此后第二句紧跟着就是一句对i的定义,因此此时一定会报link错误而不是编译错误:fatal error LNK1169: one or more multiply defined symbols found。
那么为什么反过来就不会出错呢?很简单,第一句定义了并且初始化了局部变量i,第二句extern这个变量,当extern的变量是const对象时,现在自己的文件里面向上查找,如果找到,就不会再去其他地方link,因为const本来就是文件域。那么自然不会存在刚才的link错误。你可以试一下运行结果,在main函数中将i打印出来,你会发现,i的值是1,而不是2.
问题二 分析:
常变量在定义的时候必须初始化,所以当在a.cpp中定义extern const double pi=3.14; b.pp中extern const double pi; 可以通过编译运行。因为当编译系统发现a.cpp中的全局常变量时,就知道它pi是常量,而换过来的时候,在a.cpp中定义const double pi=3.14; b.pp中extern const double pi; 编译系统在编译a.cpp是没有问题的,但到了b.cpp中就会发现,有一个外部常量是没有初始化的,而常量是不能在声明后再进行定义的,所以编译系统会认为找不到它的定义,所以就出错。
推荐阅读
- Application|linux应用编程笔记(5)系统调用文件编程方法实现文件复制
- Java|快到35岁了,担心失业(这篇文章告诉你什么才是中年危机)
- Linux|fcntl即F_SETFL,F_GETFL的使用,设置文件的flags
- Linux|关于getsockname函数的使用
- android x86虚拟机 网络正确配置
- 工具|Spring特点中关于DI,IOC及AOP的个人理解
- c#用法技巧|c# winform 通过编程取消事件(event)的注册
- C|va_list 原理以及用法
- linux|MongoDB 内存解析 Python
- 剑指offer|牛客网_剑指Offer_Python实现_更新中