局部变量的静态初始化

12

来自Scott Meyers的 Effective C++:

如果您从不调用模拟非本地静态对象的函数,则永远不会发生构造和析构对象的成本,这对于真正的非本地静态对象是不可说的。

该函数:

FileSystem& tfs()
{ 
    static FileSystem fs;
    return fs; 
}

但是标准规定:

  

如果适用,则会在首次进入其块之前执行具有静态存储期的块作用域实体的常量初始化(3.6.2)。 实现可以在与实现允许在命名空间范围内静态初始化具有静态或线程存储期变量的条件相同的情况下,提前初始化具有静态或线程存储期的其他块作用域变量。

这意味着,即使我们不调用函数 tfs(),我们也不能确定变量 fs 是否已经初始化。因为实现可以在具有静态存储期的变量上执行早期初始化。

谁是对的,或者我错了什么?


2
如果有疑问,请相信规范。《Effective C++》于1992年出版,也许事情已经发生了变化。 - Non-maskable Interrupt
1个回答

7

常量初始化是指可以在编译时确定的初始化。

只有在C++11及以后,具有非平凡构造函数的类型才能被视为:

如果构造函数是constexpr

在《Effective C++》一书中,Meyers字面上将您提出的类描述为:

class FileSystem {...};

这意味着,假设C++标准正确,只要FileSystem的提供的构造函数不是constexpr,那么即使在C++11之后,《Effective C++》也可以保持正确。


在编译时谈论初始化是否真的正确?我的意思是,常量初始化是在程序启动时执行的(或者延迟到main()语句的某个位置)。 - stella
还有一件事,constexpr构造函数将保证初始化是const初始化。因此它会在块第一次进入时执行? - stella
@Stella - constexpr构造函数允许在编译时知道值,但它也要求所有参数都是常量表达式。无论如何,如果编译器可以将已构造的对象包含在可执行文件中,则初始化不会产生运行时成本。 - Bo Persson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接