qq_21044655 2015-08-26 10:53 采纳率: 50%
浏览 3357
已采纳

c++ extern 声明 另一个文件中的定义的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;

为什么这样不能通过链接,而如果按注释里的顺序就能通过链接,这个怎么解释呢?

  • 写回答

3条回答 默认 最新

  • ronaldotong 2015-08-26 17:57
    关注

    这个问题有几个概念需要搞清楚。
    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.

    这个问题可以发散得更多。如果概念清晰就不会害怕。
    比如,我把const都去掉,会报什么错?等等。

    希望我的回答能帮助你。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用
  • ¥15 kafka topic 所有分副本数修改
  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?
  • ¥40 串口调试助手打开串口后,keil5的代码就停止了
  • ¥15 电脑最近经常蓝屏,求大家看看哪的问题
  • ¥60 高价有偿求java辅导。工程量较大,价格你定,联系确定辅导后将采纳你的答案。希望能给出完整详细代码,并能解释回答我关于代码的疑问疑问,代码要求如下,联系我会发文档
  • ¥50 C++五子棋AI程序编写
  • ¥30 求安卓设备利用一个typeC接口,同时实现向pc一边投屏一边上传数据的解决方案。