草庐IT

c++ - 局部作用域静态变量的零初始化和静态初始化

coder 2023-11-14 原文

我从 Google 阅读了几篇关于 C++ 初始化 的文章,其中一些指导我在 StackOverflow 上。我从这些帖子中挑选的概念如下:

  • C++初始化的顺序是:
    1. 零初始化
    2. 静态初始化
    3. 动态初始化
  • 静态对象(包括变量)首先被零初始化,然后是静态初始化

我有几个关于初始化问题的查询(存储类问题也可能相关):

  • 全局对象(定义时没有使用 static 关键字)也是静态对象,对吧?
  • 全局对象也像静态对象一样通过上面两步初始化,对吧?
  • 什么是静态初始化?它是指初始化静态对象(使用 static 关键字定义)吗?
  • 我还读到,当执行线程首次进入 block 时,使用 static 关键字在 block 内(即在函数中)定义的对象被初始化!这意味着 local static objectsma​​in 函数执行之前不会被初始化。这意味着它们没有像上面提到的两个步骤那样被初始化,对吧?
  • 动态初始化是指初始化new操作符创建的对象吧?它可能指的是像 myClass obj = myClass(100);myClass obj = foo();
  • 这样的初始化

我对初始化和存储类说明符问题有太多的询问。我阅读了 C++2003 标准文档,但找不到清晰的逻辑,因为它们散布在整个文档中。

我希望你能给我一个逻辑上解释存储类说明符和初始化的整个映射的答案。欢迎任何引用!

可以解释我的问题的代码:

class myClass{
public:
   int i;
   myClass(int j = 10): j(i){}
   // other declarations
};

myClass obj1;//global scope
static myClass obj2(2);//file scope
{   //local scope
   myClass obj3(3);
   static myClass obj4(4);
}

编辑:
如果你觉得我的问题比较繁琐,你可以根据上面的代码帮忙解释一下你的想法。

最佳答案

I read several posts on C++ initialization from Google, some of which direct me here on StackOverflow. The concepts I picked from those posts are as follows:

  • The order of initialization of C++ is:
    1. Zero Initialization;
    2. Static Initialization;
    3. Dynamic Initialization.

是的,确实有 3 个阶段(在标准中)。在继续之前让我们澄清一下:

  • 零初始化:内存在字节级用0填充。
  • 常量初始化:在对象的内存位置复制一个预先计算的(编译时)字节模式
  • 静态初始化:零初始化后常量初始化
  • 动态初始化:执行一个函数来初始化内存

一个简单的例子:

int const i = 5;     // constant initialization
int const j = foo(); // dynamic initialization
  • Static objects (variables included) are first Zero-initialized, and then Static-initialized.

是也不是。

标准要求对象首先被零初始化,然后它们是:

  • 如果可能的话初始化常量
  • 否则动态初始化(编译器无法在编译时计算内存内容)

注意:在常量初始化的情况下,编译器可能会按照 as-if 规则忽略第一个零初始化内存。

I have several inquiries as to the initialization issue (storage class issue may be related as well):

  • Global objects (defined without static keyword) are also static objects, right?

是的,在文件范围内,static 对象只是符号的可见性。全局对象可以通过名称从另一个源文件中引用,而 static 对象名称对于当前源文件来说是完全本地的。

混淆源于世界 static 在许多不同情况下的重用 :(

  • Global objects are also initialized like static objects by two steps like above, right?

是的,事实上本地静态对象也是如此。

  • What is the Static Initialization? Does it refer to initializing static objects (defined with static keyword)?

不,如上所述,它指的是在不执行用户定义的函数的情况下初始化对象,而是将预先计算的字节模式复制到对象的内存中。请注意,对于稍后将动态初始化的对象,这只是将内存归零。

  • I also read that objects defined within block (i.e. in a function) with static keyword is initialized when the execution thread first enters the block! This means that local static objects are not initialized before main function execution. This means they are not initialized as the two steps mentioned above, right?

它们是用两步过程初始化的,尽管实际上只有第一次执行通过它们的定义。所以过程相同,但时间略有不同。

但在实践中,如果它们的初始化是静态的(即,内存模式是编译时模式)并且它们的地址未被获取,则它们可能会被优化掉。

请注意,在动态初始化的情况下,如果它们的初始化失败(应该初始化它们的函数抛出异常),将在下一次流控制通过它们的定义时重新尝试。

  • Dynamic initialization refers to initialization of objects created by new operator, right? It might refer to initialization like myClass obj = myClass(100); or myClass obj = foo();

根本不是,它指的是需要执行用户定义函数的初始化(注意:就 C++ 语言而言,std::string 具有用户定义的构造函数)。

编辑: 感谢 Zach 指点我,我错误地将 C++11 标准称为常量初始化的静态初始化;现在应该修复此错误。

关于c++ - 局部作用域静态变量的零初始化和静态初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17801075/

有关c++ - 局部作用域静态变量的零初始化和静态初始化的更多相关文章

  1. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  4. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  5. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  6. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  7. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  8. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  9. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  10. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

随机推荐