静态和动态初始化仅适用于非局部变量吗?

5 c++

这是代码:

int factorial(int n)
{
     if ( n < 0 )       return -1; //indicates input error
     else if ( n == 0 ) return 1;
     else               return n * factorial(n-1);
}

int const a = 10 ; //static initialization 
             //10 is known at compile time. Its 10!

int const b = factorial(8); //dynamic initialization 
                      //factorial(8) isn't known at compile time,
                      //rather it's computed at runtime.
Run Code Online (Sandbox Code Playgroud)

(从这里被盗)

因此,对我来说,为什么b动态初始化并a静态初始化是有道理的.

但是,如果a并且b具有自动存储持续时间(可能已经初始化main()),那么您是否仍可以将其初始化称为静态或动态?因为对我来说,它们听起来像初始化的一般名称,而不是复制初始化.

另外,我已经读过这个,有人可以告诉我为什么他们没有直接解释静态和动态初始化是什么?我的意思是,看起来他们只是解释了他们发生了什么情况,但也许有原因?

cppreference声明初始化器可以调用(一些初始化,比如值初始化等),但是在本文后面,他们提到了静态和动态初始化,就好像这两个是一些初始化的更通用的名称.这可能听起来令人困惑,但在这里我已经说明了我的理解:

在此输入图像描述

(不是最美丽的东西)

mks*_*eve 3

静态和动态初始化描述了加载二进制文件并到达 main 准备运行的过程。

静态初始化描述了编译器可以在编译时计算出的信息,并允许将固定值存储在二进制文件中,因此当操作系统加载二进制文件时,它具有正确的值。

动态初始化描述了编译器在main运行之前插入的代码,它初始化了编译器无法计算的信息。这可能是因为它直接涉及代码,或者它引用了编译器在编译时不可见的信息。

但是如果a和b有自动存储期限怎么办

当 a 是有限范围的自动变量时的简单情况。

int a = 12;
Run Code Online (Sandbox Code Playgroud)

这无法静态初始化,因为编译器不知道在哪里初始化 a,因为每次调用它的每个线程都会不同。

编译器将能够用类似的东西初始化 a 。

  mov (_addr_of_a), 12
Run Code Online (Sandbox Code Playgroud)

由于 _addr_of_a 在运行时之前是未知的,并且值 12 嵌入在代码中,因此不会完成静态初始化它的情况。

更复杂的情况...

int a[] = { /* some integer values */ };
Run Code Online (Sandbox Code Playgroud)

这可能由编译器作为静态和动态代码的混合来实现,如下所示。

static int a_init = { /* some integer values */ };
memcpy( a, a_init, length_in_bytes_of_a );
Run Code Online (Sandbox Code Playgroud)

因此,在某些情况下,静态初始化会“泄漏”到运行时行为。

动态行为的问题更大——它假设一个函数通常不公开其实现,执行时间很慢,并且constexpr在结果开始时为缓存赋予价值。我还没有看到这种优化发生。

静态和动态初始化是描述创建正在运行的程序的过程的技术术语。局部变量可能存在类似的模式,但它们不属于staticdynamic初始化的技术定义。