zoukankan      html  css  js  c++  java
  • C/C++11 存储类说明符

    概念

    链接属性

    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

  • 相关阅读:
    js与jquery常用数组方法总结
    js 对象深复制,创建对象和继承
    Web前端面试常识
    jQuery插件开发之boxScroll与marquee
    jQuery插件开发之windowScroll
    《将博客搬至CSDN》
    蓝桥杯 翻硬币
    AcWing 756.蛇形矩阵
    货仓选址
    费解的开关
  • 原文地址:https://www.cnblogs.com/wangzhiyi/p/13507563.html
Copyright © 2011-2022 走看看