为什么文件范围静态变量必须初始化为零? [英] Why file scope static variables have to be zero-initialized?

查看:152
本文介绍了为什么文件范围静态变量必须初始化为零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++默认初始化不会通过自动存储将变量清零,为什么要对静态存储变量进行特殊处理?

C++ default initialization doesn't zero out variables with auto storage, why the special treatment for static storage variables?

C和C ++所定义的内容是否必须与之兼容?如果是这种情况,为什么C决定进行零初始化?

Was it something defined by C and C++ just have to be compatible with? If that's the case why C decides to do zero-initialization?

如果文件范围的静态变量提供了初始化程序,则将首先对其进行零初始化,然后再次进行常量/动态初始化.那不是多余的吗?例如,以下代码来自cppreference: http://en.cppreference.com/w /cpp/language/zero_initialization

If a file scope static variables is provided with a initializer, they will be zero-initialized first and then constant/dynamic initialized again. Isn't that redundant? For example the following code is from cppreference:http://en.cppreference.com/w/cpp/language/zero_initialization

#include <string>

double f[3]; // zero-initialized to three 0.0's
int* p;   // zero-initialized to null pointer value
std::string s; // zero-initialized to indeterminate value
               // then default-initialized to ""
int main(int argc, char* argv[])
{
    static int n = argc; // zero-initialized to 0
                         // then copy-initialized to argc
    delete p; // safe to delete a null pointer
}

在这种情况下,为什么不能 n 直接将其初始化为argc?

In this case, why n can't be initialized to argc directly?

此问题的一部分已被此处的问题回答:静态变量初始化? 但是我不认为这是重复的,因为另一个问题的答案没有回答我的第二个问题.为什么2分阶段进行初始化. 此外,另一篇文章的标题并没有真正说明问题到底是什么.

Part of this question has been answered by the question here: Static variable initialization? But I don't think it's a duplicate because the answers in the other question didn't answer my second question, ie. why the 2 staged initialization. Besides, the title of the other post doesn't really say what exactly the question is.

推荐答案

开发C的操作系统上的行为影响了这些标准规定.在加载应用程序时,操作系统加载程序会为 BSS 提供一些内存.最好将其清除为零,因为如果其他某个进程较早使用了该内存,则您正在启动的程序可能会窥探先前进程的内存内容,从而可能会看到密码,对话或其他数据.并非每个早期或简单的OS都关心此事,但大多数人都关心,所以在大多数情况下,初始化实际上是免费的",因为OS仍将执行此任务.

The behaviour on the Operating Systems where C was developed has shaped these Standard stipulations. As applications load, the OS loader provides some memory for the BSS. It's desirable to clear it to zeros because if some other process had been using that memory earlier, the program you're starting could snoop on the prior process's memory contents, potentially seeing passwords, conversations or other data. Not every early or simple OS cares about this, but most do, so on most the initialisation is effectively "free" as it's a task the OS will do anyway.

将此默认值设置为0可使实现易于查看动态初始化期间设置的标志,因为将不会读取未初始化的内存,也不会因此而产生未定义的行为.例如,给定...

Having this default of 0 makes it easy for the implementation to see refer to flags set during dynamic initialisation, as there will be no uninitialised memory read and consequent undefined behaviour. For example, given...

void f() { static int n = g(); }

...编译器/实现也可能隐式添加类似static bool __f_statics_initialised的变量-由于归零行为,幸运地"默认为0/false-以及类似于(a的初始化代码线程安全版本)...

...the compiler/implementation may implicitly add something like a static bool __f_statics_initialised variable too - which "luckily" defaults to 0 / false due to the zeroing behaviour - along with initialisation code akin to (a possibly thread safe version of)...

if (!__f_statics_initialised)
{
    n = g();
    __f_statics_initialised = true;
}

对于上述情况,初始化是在第一次调用时完成的,但是对于全局变量,它是在调用main()之前的某个时间以未指定的每个对象的顺序完成的.在那种情况下,具有一些特定于对象的初始化代码和动态初始化能够将未初始化状态下的静态变量与需要将其设置为非零值的静态变量区分开来,从而使编写稳定的启动代码变得更加容易.例如,函数可以检查非本地静态指针是否仍然为0,如果不是,则为该对象new.

For the above scenario the initialisation is done on first call, but for global variables it's done in an unspecified per-object ordering, sometime before main() is invoked. In that scenario, having some object-specific initialisation code and dynamic initialisation able to differentiate statics in uninitialised state from those they know need to be set to non-zero values makes it easier to write robust start-up code. For example, functions can check if a non-local static pointer is still 0, and new an object for it if so.

值得注意的是,许多CPU都具有高效的指令,可以将大量的内存清零.

It's also noteworthy that many CPUs have highly efficient instructions to zero out large swathes of memory.

这篇关于为什么文件范围静态变量必须初始化为零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆