概念

链接属性

linkage,链接属性是描述链接器应如何链接变量的属性。链接属性决定某变量是否可供另一个文件使用,或者是否只在声明它的文件中使用

  • 外部链接属性
    - 本编译单元中有外部链接属性的变量/函数可被所有其他编译单元访问
    - 其内存通常在程序启动前的加载阶段被分配

  • 内部链接属性
    - 其他编译单元不可访问本编译单元中有内部链接属性的变量/函数
    - 仅当变量具有全局作用域时才能实现内部链接
    - 静态全局变量、常量全局变量为内部链接
    - 顶级名字空间范围(C中的文件范围)中被const而不是extern修饰的变量在C中具有外部链接,但在C++中具有内部链接
    - 其内存通常在程序启动前的加载阶段被分配

生存期

storage duration,存储持续时间。与变量保存位置相关,变量从被分配内存,到释放其占用的内存。具体可参考Linux 进程内存分布

  • 自动存储持续时间
    - 举例如普通局部变量

  • 静态存储持续时间
    - 在程序开始时分配对象的存储空间,在程序结束时释放对象的存储空间
    - 只有一个实例
    - 举例
    - 在名字空间范围内声明的所有对象(包括全局名称空间)
    - 使用static或extern声明的对象

  • 线程存储持续时间
    - 对象的存储在线程开始时分配,并在线程结束时释放
    - 每个线程都有其自己的对象实例
    - 举例如声明为thread_local的对象

  • 动态存储持续时间
    - 通过使用动态内存分配功能,可以按请求分配和释放对象的存储

作用域

scope,有效范围,这是一个在编译阶段的概念。例如代码中的变量或函数,有的可以在整个程序中的所有范围内起作用,这称为“全局”的变量或函数;有的只能在一定的范围内起作用,称为“局部”变量。

可见性

当作用域发生嵌套,并且内层的变量和外层的变量同名时,在内层里,外层的变量暂时地失去了可见性

存储类说明符

static

仅在对象声明(函数参数列表中除外),函数声明(块范围中除外)和匿名联合的声明中才允许使用static说明符

  • 类成员的声明中使用
    - 声明一个静态成员

  • 在对象声明时使用(不包括带有thread_local)
    - 指定静态存储持续时间

  • 在命名空间范围的声明中使用
    - 指定内部链接

extern

仅在变量和函数的声明中(类成员或函数参数除外)允许使用extern说明符

  • 指定外部链接
  • 不影响存储持续时间,但是不能在自动存储持续时间对象的定义中使用它,因此所有被extern修饰的对象都具有静态或线程持续时间
  • 使用extern并且没有初始化程序的变量仅仅是声明,而不是定义

thread_local

仅在命名空间范围内声明的对象,在块范围内声明的对象和静态数据成员才允许使用thread_local说明符。使用thread_local说明符声明的变量仅可在它在其上创建的线程上访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。

  • 指示对象具有线程存储持续时间
  • 可以将其与static或extern组合以分别指定内部或外部链接(始终具有外部链接的静态数据成员除外),但是附加的static不会影响存储时间
  • 在块范围内被thread_local修饰变量,隐式地也被static修饰

使用场景:

  • 全局thread_local变量
    - 在被访问之前,按照声明/定义语句执行初始化
    - 如果不访问则不会被初始化
    - 举例如:声明/定义某个复杂类型,多个线程中进行访问而互不影响;并且单个线程只在线程启动后(访问thread_local变量前)对thread_local变量进行初始化一次

  • 局部thread_local变量
    - 即在块范围内声明/定义的thread_local变量,其同时被隐式的声明为static,当代码经过其声明/定义语句时进行初始化,并且只会初始化一次
    - 举例如:某个操作内部需要初始化一个复杂类型,有多个线程并发重复的执行这个操作。将这个复杂类型实例声明/定义为局部thread_local变量可以实现多个线程中的复杂类型实例互相隔离;并且单个线程重复执行这个操作时,只初始化复杂类型实例一次

mutable

register

静态局部变量

  • 在块范围内使用static或thread_local说明符声明的变量具有静态或线程存储期限
  • 如果多个线程尝试同时初始化同一静态局部变量,则初始化仅发生一次

参考

Storage class specifiers
Internal Linkage and External Linkage in C

posted on 2020-08-15 09:28  chenguang9239  阅读(358)  评论(0编辑  收藏  举报