【问题标题】:Is the initialization of global variable the same as the initialization of static variable inside a function全局变量的初始化和函数内部静态变量的初始化一样吗
【发布时间】:2021-03-01 10:15:04
【问题描述】:

我正在尝试找出 C++ 中所有不同类型的初始化。现在我正在阅读这个链接:https://en.cppreference.com/w/cpp/language/zero_initialization

在这个链接的例子中,我们有这样一段代码:

std::string s; // zero-initialized to indeterminate value
               // then default-initialized to ""

据我了解,全局变量的初始化如下:

当我们编译代码时,s 是零初始化的,它被放在二进制文件的.bss 段中。当我们运行二进制文件时(意味着内核开始将二进制文件加载到 RAM 中),s 被默认初始化为空字符串""

现在,我们定义一个函数如下:

void func()
{
    static std::string s;
}

如果我们第一次调用该函数,s 将被初始化,这是肯定的。但是还是用两种方法初始化:先零初始化,再默认初始化,就像第一个s一样?

顺便说一句,我正在使用编译器 GCC 7.5 开发 Ubuntu X86_64 架构。 如果我的问题没有被 C++ 标准化,你可以在评论中告诉我,我会关闭这个问题。

【问题讨论】:

  • Case (2) 可能属于 "as-if" 规则 - 因为在调用 func 然后编译器之前您无法观察 s 的状态可以做自己喜欢的事;由于s 不在func 之外使用,因此s 甚至不需要存在。
  • C++ 没有“段”或“内核”的概念。如果您想知道特定实现如何在特定平台上工作,请将该信息添加到问题中。
  • 即使在确实有段的系统上,也由编译器决定是否使用它们。仅用于异常处理的变量?很有可能它经常未被使用,因此优化器可能决定仅在首次使用时分配存储空间。

标签: c++ static initialization static-initialization


【解决方案1】:

但它是否仍然用两种方法初始化:第一个零 初始化,然后是默认初始化,就像第一个s一样?

假设,“as-if”规则有效地强制编译器考虑这个变量的存在,是的。标准摘录:

以下情况会进行零初始化:

  1. 对于每个具有静态或线程本地存储的命名变量 不受持续初始化的持续时间,在任何之前 其他初始化。

默认初始化在三种情况下进行:

  1. 当变量具有自动、静态或线程本地存储时 声明了没有初始化器的持续时间;

正如 molbdnilo 在 cmets 中所说,如果您只对标准声称的行为感兴趣,那么您应该完全避免在这里考虑二进制文件、内核和段。

【讨论】:

    猜你喜欢
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多