7-12 作用域、存储期和链接总结

作用域scope存储期duration链接linkage这三个概念容易引发诸多困惑,因此我们将额外安排一节课进行系统总结。其中部分内容尚未讲解,此处仅为完整性考虑及后续参考而保留。


作用域概述

标识符的作用域决定了该标识符在源代码中可被访问的位置。

  • 具有块(局部)作用域block (local) scope的变量仅可在声明点至其所在块(包括嵌套块)结尾之间被访问。这包括:

    • 局部变量
    • 函数形参
    • 在代码块内声明的程序定义类型(如枚举和类)
  • 全局作用域global scope的变量和函数可在声明点至文件结尾范围内访问,包括:

    • 全局变量
    • 函数
    • 在命名空间内或全局作用域中声明的程序定义类型(如枚举和类)

存储期概述

变量的存储期决定了其创建与销毁的时机。

  • 具有自动存储期automatic duration的变量在定义处创建,并在所属代码块结束时销毁。包括:
    • 局部变量
    • 函数形参
  • 具有静态存储期static duration的变量在程序开始时创建,程序结束时销毁。包括:
    • 全局变量
    • 静态局部变量
  • 具有动态存储期static duration的变量由程序员请求创建和销毁。包括:
    • 动态分配的变量

链接概述

标识符的链接linkage决定了在不同作用域中对同一标识符的声明是否指向同一实体(对象、函数、引用等)。
局部变量不具有链接。每个无链接的标识符声明都指向一个独特的对象或函数。

  • 不具有链接no linkage的标识符意味着相同标识符的其他声明指向独立实体。具有无作用域标识符的实体包括:

    • 局部变量
    • 在代码块内声明的程序定义类型标识符(如枚举和类)
  • 具有内部链接internal linkage的标识符意味着相同翻译单元内相同标识符的声明指向同一对象或函数。具有内部作用域标识符的实体包括:

    • 静态(static)全局变量 (初始化或未初始化)
    • 静态(static)函数
    • 常量(const)全局变量
    • 未命名的命名空间及其内部定义的任何内容
  • 具有外部链接external linkage的标识符意味着整个程序中相同标识符的声明都指向同一个对象或函数。具有外部链接的标识符实体包括:

    • 非静态(non-static)函数
    • 非常量(non-const)全局变量(初始化或未初始化)
    • 外部常量(extern const)全局变量
    • 内联常量(inline const)全局变量
    • 命名空间(namespace)

当外部链接标识符的定义被编译到多个.cpp文件中时,通常会引发重复定义链接错误(违反单一定义规则)。此规则存在例外情况(涉及类型、模板及内联函数/变量)——我们将在后续讲解相关主题时详细说明。

另请注意函数默认具有外部链接。可通过static关键字将其限定为内部作用域。


变量作用域、存储期与链接总结

由于变量具有作用域、存储期和链接特性,让我们通过图表进行总结:

Type Example Scope Duration Linkage Notes
Local variable int x; Block Automatic None
Static local variable static int s_x; Block Static None
Dynamic local variable int* x { new int{} }; Block Dynamic None
Function parameter void foo(int x) Block Automatic None
Internal non-const global variable static int g_x; Global Static Internal Initialized or uninitialized
External non-const global variable int g_x; Global Static External Initialized or uninitialized
Inline non-const global variable (C++17) inline int g_x; Global Static External Initialized or uninitialized
Internal constant global variable constexpr int g_x { 1 }; Global Static Internal Must be initialized
External constant global variable extern const int g_x { 1 }; Global Static External Must be initialized
Inline constant global variable (C++17) inline constexpr int g_x { 1 }; Global Static External Must be initialized

前向声明概述

可通过前向声明访问其他文件中的函数或变量。声明变量的作用域遵循常规规则(全局变量为全局作用域,局部变量为块作用域)。

Type Example Notes
Function forward declaration void foo(int x); Prototype only, no function body
Non-constant variable forward declaration extern int g_x; Must be uninitialized
Const variable forward declaration extern const int g_x; Must be uninitialized
Constexpr variable forward declaration extern constexpr int g_x; Not allowed, constexpr cannot be forward declared

constexpr 变量(其隐含为 const)可通过 const 变量前向声明进行前向声明。当通过前向声明访问该变量时,该变量将被视为 const(而非 constexpr)。


存储类限定符到底是什么?

当作为标识符声明的一部分使用时,static 和 extern 关键字被称为存储类限定符storage class specifiers。在此上下文中,它们设置标识符的存储期和链接。

C++ 支持 4 种有效的存储类限定符:

Specifier Meaning Note
extern static (or thread_local) storage duration and external linkage
static static (or thread_local) storage duration and internal linkage
thread_local thread storage duration
mutable object allowed to be modified even if containing class is const
auto automatic storage duration Deprecated in C++11
register automatic storage duration and hint to the compiler to place in a register Deprecated in C++17

存储类限定符这一术语通常仅用于正式文档中。

posted @ 2026-02-23 10:22  游翔  阅读(3)  评论(0)    收藏  举报