以下是代码:
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.
(从here被盗)
因此,为什么动态初始化b
并静态初始化a
是有道理的。
但是,如果a
和b
具有自动存储持续时间(可能已在main()
中初始化),那么您是否仍然可以将其初始化称为静态或动态?因为对我来说,它们听起来像初始化的一般名称,而不是复制初始化。
另外,我已阅读this,有人可以告诉我为什么他们没有直接解释静态和动态初始化是什么?我的意思是,看起来他们只是解释了他们发生了什么情况,但也许有原因?
cppreference声明初始化程序可以调用(一些初始化,比如值初始化等),但是在本文的后面,他们提到了静态和动态初始化,就好像这两个是一些初始化的更通用的名称。这听起来可能令人困惑,但在这里我已经说明了我的理解:
(不是最漂亮的东西)
答案 0 :(得分:2)
静态和动态初始化描述了加载二进制文件并进入main准备好运行时的过程。
静态初始化描述了编译器在编译时可以解决的信息,并允许将固定值存储在二进制文件中,因此在操作系统加载二进制文件时,它具有正确的值。
动态初始化描述了编译器在主运行之前插入的代码,它初始化了编译器无法计算的信息。这可能是因为它直接涉及代码,或者它指的是编译时编译器不可见的信息。
但是如果a和b有自动存储持续时间
a是有限范围的自动变量的简单情况。
int a = 12;
这不能静态初始化,因为编译器不会知道在哪里初始化a,因为每次都会有所不同,并且在每个调用它的线程上都会有所不同。
编译器可以用类似的东西来初始化。
mov (_addr_of_a), 12
由于_addr_of_a在运行时是未知的,并且值12嵌入在代码中,因此不会进行静态初始化的情况。
更复杂的案例......
int a[] = { /* some integer values */ };
这可能由编译器实现为静态和动态代码的混合,如下所示。
static int a_init = { /* some integer values */ };
memcpy( a, a_init, length_in_bytes_of_a );
因此,有些情况会从静态初始化到运行时行为“泄漏”。
动态行为更成问题 - 它假定一个通常不暴露其实现的函数具有较慢的执行时间,并且是constexpr
在结果开始时为缓存赋值。我没有看到这种优化发生。
静态和动态初始化是描述创建正在运行的程序的过程的技术术语。局部变量可能存在类似的模式,但它们不属于static
和dynamic
初始化的技术定义。