Skip to content

Object storage duration

storage duration和lifetime是object的重要属性,这两个属性是密切相关的,在cppreference Object中对此进行了介绍,本文讨论object的storage duration。

Guide

原文的内容是比较杂乱的,既包含了**storage duration**又包含了**linkage**,实际上它们两者是independent property of object,所以应该分开来进行讨论,对linkage的讨论,在C++implementation\Link\Linkage章节;

原文之所以将它们放到一起是因为:C++和C并没有提供专门分别描述这两种property的specifier,而是提供的合并的specifier,关于这一点,在cppreference Storage class specifiers中进行了详细的讨论。

我们按照在Theory\Programming-language\How-to-master-programming-language中总结的:首先学习property,然后学习描述这些property的specifier的方式来进行学习。

本文仅仅关注原文中object storage duration相关的内容,我们以如下的思路来组织内容:

topic 注解
storage duration C++ object有哪几种storage duration
Storage class specifiers C++ language提供了哪些specifier来供programmer对storage duration进行控制/描述,即C++ language中,有哪些Storage class specifiers

所以,本文与原文的组织有所差异。

cppreference Storage class specifiers

Storage duration

NOTE:

统一描述方式: object with ***storage duration

本节标题的含义是: 后面为了描述的统一性,我们统一使用"object with ***storage (duration)"格式,括号括起来的部分,表示是optional;下面是例子:

描述具备automatic storage duration的object: object with automatic storage ;

描述具备static storage duration的object: object with static storage ;

本节内容组织

C++\Language-reference\Basic-concept\Object\Lifetime-and-storage-duration\Lifetime中,已经说明了object lifetime中的activity,在其中的"Object and storage"章节中,已经论述了lifetime of object 和 storage duration之间的关系,本节以storage duration为分类标准,描述各种object的lifetime。

下面的表格重要描述allocation activity和dealloaction activity,列说明:

列object: 描述哪些object具备对应的storage duration;

列scope: 从OS的角度来分析storage duration;

列"allocation": 描述的是"allocation time point";

列"dealloaction": 描述的是"dealloaction time point";

后面的非表格内容,对各种storage duration进行说明,其中会initialization、deinitialization的内容。

所以,根据这两大块内容,读者能够对object的lifetime有一个非常完整、清晰的认识。

storage duration allocation dealloaction objects scope
automatic allocated at the beginning of the enclosing code block C++: deallocated at the beginning of the enclosing code block
C: deallocated when it is exited by any means (goto, return, reaching the end)
1. local objects, except those declared
staticstatic object),
externextern object) or
thread_local.
stack;
function;
thread allocated when the thread begins
(Before thread function execution)
deallocated when the thread ends 1. objects declared thread_local have this storage duration stack;
thread;
static allocated when the program begins
(Before main function)
deallocated when the program ends 1. objects declared at namespace scope (including global namespace)
2. those declared with static or extern (包括:
static local object
extern local object
process;
dynamic allocated by using dynamic memory allocation function deallocated by using dynamic memory deallocation function heap;

NOTE: 上述storage duration是C++ language对OS中process execution model、memory model的刻画,参见工程Linux-OS的Multitasking\Process-model\Process-run-model章节。

NOTE:

Lifetime of object with static and thread-local storage duration

C++语言中,对object的lifetime是受到了object的storage duration属性的影响的,对于上述四种storage duration,由于它们的allocation time point不同,就造成了它们的initialization time point的不同;其中比较特殊的是static storage duration和thread storage duration,cppreference中,对它们的描述主要是如下两篇文章:

Non-local variables and Static local variables

它们是比较分散的,我将它们进行了整理:

C++\Language-reference\Basic-concept\Object\Lifetime-and-storage-duration\Thread-local-storage-duration

C++\Language-reference\Basic-concept\Object\Lifetime-and-storage-duration\Static-storage-duration

Automatic storage duration

对于object with automatic storage duration,它的initialization、deinitialization没有说明特殊之处。

我们平时所说的"自动变量"就具备这种storage duration;

Automatic storage and RAII

object with automatic storage的lifetime is bound by "{}",对这个特性的一个非常重要的应用就是: RAII,参见RAII

Dynamic storage duration

对于object with dynamic storage duration,在Resource-management\Memory-management章节进行了描述。

Static storage duration

对于object with static storage duration,相比于其它类型的object,它的initialization、deinitialization是比较复杂的,原文中有专门说明:

See Non-local variables and Static local variables for details on initialization of objects with this storage duration.

在前面的注解中,已经描述了我的整理思路。

Thread local duration

这是C++11引入的,源于"C++11 introduced a standardized memory model",关于此,参见C++\Language-reference\Basic-concept\Abstract-machine\Memory-model

对于对于object with thread storage duration相比于其它类型的object,它的initialization、deinitialization是比较复杂的,原文中有专门说明:

See Non-local variables and Static local variables for details on initialization of objects with this storage duration.

在前面的注解中,已经描述了我的整理思路。

Example: automatic storage duration: extern local object

来源:How does linker handle variables with different linkages? # A

#include <iostream>

static int x; // a namespace scope, so `x` has internal linkage, static storage duration

int f()
{
    extern int x; // static storage duration
    ++x;
}

int g()
{
    extern int x; // static storage duration
    std::cout << x << '\n';
}

int main()
{
    g();
    f();
    g();
}
// g++ test.cpp

Storage class specifiers

NOTE: 本节描述描述storage duration的specifier

specifier storage duration linkage function
auto (until C++11) automatic no linkage 不可修饰function
register (until C++17) automatic no linkage 不可修饰function
static static or thread internal 可以修饰function
extern static or thread external 可以修饰function
thread_local(since C++11) thread 不可修饰function
mutable does not affect storage duration or linkage. See const/volatile for the explanation. 不可修饰function

NOTE:

无论是C++还是C,都没有专门描述linkage的specifier,而是将描述**storage duration**和描述**linkage**的specifier合并在一起,对于linkage,并没有单独描述它的specifier,但是,compiler提供了default linkage;关于这一点,我们需要仔细阅读cppreference Storage class specifiers 和 creference Storage-class specifiers

cppreference Storage class specifiers 中,对specifiers的描述如下:

The storage class specifiers are a part of the decl-specifier-seq of a name's declaration syntax. Together with the scope of the name, they control two independent properties of the name: its storage duration and its linkage.

C++中,将这些specifier称为 storage class specifier。

creference Storage-class specifiers 中,对specifiers的描述如下:

Specify storage duration and linkage of objects and functions

C中,将这些specifier称为 storage class specifier。

我们需要深入思考:为什么将linkage和storage duration的specifier合并?

关于此的原因之一可以参看下面对extern的Explanation,原因之二则是出于语言设计者出于对语言简便性的考虑(在Theory\Programming-languageDesign-of-programming-language.md\#Design of specifier中进行了讨论)

extern

It specifies external linkage, and does not technically affect storage duration, but it cannot be used in a definition of an automatic storage duration object, so all extern objects have static or thread durations. In addition, a variable declaration that uses extern and has no initializer is not a definition.

NOTE: 上面这段话的意思是:extern variable只能够link to object with static storage or object with thread_local storage,所以extern variable的storage duration是static的,这是因为显然它需要compiler和linker在编译阶段就能够找到这个object。

linkage and storage duration of function

需要注意的是:对于function而言,它没有**storage duration** property,只有**linkage** property,对于function而言,讨论它的storage duration是没有意义的。对于object而言,它既有**storage duration** property,又有**linkage** property。

staticextern 也可以 修饰 function,来控制它的linkage。

对于static function,参见C-and-C++\specifiers\static\Static-function

对于extern function,目前没有进行总结。

static specifier and static storage duration

使用static specifier修饰的object具有static storage duration,但是具有static storage duration的object,不一定要使用static specifier来修饰。

NOTE:

这是C++的晦涩之处

Static local variables

对于static local variable,参见C++\Language-reference\Basic-concept\Object\Lifetime-and-storage-duration\Static-storage-duration\Static-local-variables章节

Storage duration of temporary object

Temporary object的storage duration是什么呢?在cppreference Lifetime # “Temporary object lifetime” 章节对它的lifetime进行了描述,可以肯定的是,temporary object的storage duration是无法用上述四种storage duration进行描述的。