C++中的内部连接和外部连接

(必须吐槽一句,博客园的审批对于这样的细节问题似乎有点不屑,恰恰这样的问题才是记录在这里常翻阅的,否则项目代码上git,放这里干什么)

首先,由global变量引出我们今天的问题:

C++中global变量是全局可见的,可以在不同的compilation unit(编译单元)中使用。

如下两个文件:

1.cpp

int a = 1;

2.cpp

#include<iostream>

extern int a;

int main()

{
  std::cout<<a<<std::endl;//输出1

}

________________________________________________________________________

提醒一下,这里的int a 是全局变量,属于静态变量,存储在静态数据段。

又static关键字,通常用在一个局部变量,使之变为静态变量。如果用在一个global变量上,当然,这个global变量还是静态的。只是,它变为了局部可见:在自己所在的compilation unit可见。

1.cpp

static int a = 1;

2.cpp

#include<iostream>

extern int a;

int main()

{
  std::cout<<a<<std::endl; //编译可通过,出现链接错误!

}

编译通过,但链接错误的原因是,我们在编译阶段,因为extern int a这句话告诉编译器,a在某个地方定义,它是有效的。但是,在链接时,链接器找不到int a的定义。

问题出在1.cpp中的static关键字上,它使得全局变量a的由外部连接的属性变为了内部连接:只在自己的compilation unit可见,链接器不对其他compalition unit可见。所以,我们上面的程序中,链接器找不到int a。

记住,全局变量是静态变量,static global也是静态变量,但是,它们的链接属性不一样。

————————————————————————————————————————————————————————————

具有内部连接的关键字还有const。

static 和 extern不能对同一个变量同时声明。

但const和extern不是同一存储类别,可以同时用在同一个变量的声明。所以,我们可以用使用extern关键字修改const的连接属性

1.cpp

const int a = 21;

2.cpp

#include<iostream>

extern const int a;

int main()

{
  std::cout<<a<<std::endl; //编译可通过,出现链接错误!

}

修改为

1.cpp

extern const int a = 21;

2.cpp

#include<iostream>

extern const int a;//注意,这里的const不可以略去

int main()

{
  std::cout<<a<<std::endl; //输出21

}

————————————————————————————————————————————————————————————

在C++中具有内部连接属性的有:static的全局变量,枚举类型的定义,类的定义,内联函数的定义,union的定义,名字空间中const定义。

(最后,提醒一个容易犯错的地方:在函数体外定义:const char* p = "xx";p是外部连接的,因为const没有修饰p)

原文地址:https://www.cnblogs.com/wangpei0522/p/4459624.html