问题标签 [static-initialization]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 如何防止链接器优化启动代码?
我有以下问题:我的(C++-)项目由几个子项目组成。在每个文件中,我都有几个文件,其中包含我想在启动时运行的代码。到目前为止,我的解决方案是使用静态变量,这些变量在初始化时调用相应的代码,如下所示:
在为每个子项目使用 dll 构建我的项目时,一切正常,代码按预期运行。然而,当静态链接子项目时,链接器确定 Foo.o 不包含从外部引用的任何代码,并将其优化掉。当然,我可以在其他地方添加对 sFooRegistry 的引用,但这很乏味且容易出错。
有什么(符合标准的)解决这个问题的方法?
好的,我可以在 mac/gcc 和 win/visual studio 上做什么?
c++ - 在静态初始化期间可以安全地创建线程吗?
在某些时候,我记得读到在 main() 的第一行之前无法安全地创建线程,因为编译器插入特殊代码以使线程在静态初始化期间运行。因此,如果您有一个在构造时创建线程的全局对象,您的程序可能会崩溃。但是现在我找不到原始文章了,我很好奇这是一个多么严格的限制——按标准严格来说是真的吗?大多数编译器都是这样吗?在 C++0x 中它会保持不变吗?符合标准的编译器是否可以使静态初始化本身成为多线程的?(例如检测两个全局对象不相互接触,并在单独的线程上初始化它们以加速程序启动)
编辑:为了澄清,我试图至少了解实现在这方面是否真的有很大差异,或者它是否是伪标准的东西。例如,从技术上讲,该标准允许改组属于不同访问说明符(公共/受保护/等)的成员的布局。但是我所知道的编译器实际上没有这样做。
c++ - 在代码中找到静态变量的最简单方法?
我的盘子上有一个错误,用于在我们的一个库中定位和重写一个静态变量,这占用了我们应用程序的启动时间。我不熟悉库代码库,并要求提供良好的启发式/技术/grep 命令/等。这会减轻我识别所述静态变量位置的任务吗?
(PS 我已经在搜索代码库了static
;不用说这是一个冗长的结果。)
更新:错误报告简单地指出“库 XYZ 在静态初始化时需要 N 毫秒”;我没有更多关于静态变量的信息。我没有分析日志,但我会看看我是否可以从错误报告者那里得到它们。
java - 静态变量初始化?
我想知道为什么 C、C++ 和 Java 中的静态变量默认初始化为零?为什么这不适用于局部变量?
c++ - C++ 静态初始化在同一个回溯中出现两次是否正常?
我正在尝试调试使用 GCC 编译的 C++ 程序,该程序在启动时冻结。GCC 互斥锁保护函数的静态局部变量,似乎等待获取这样的锁是它冻结的原因。这是如何发生的相当令人困惑。第一个模块 A 的静态初始化发生(有 __static_init 函数 GCC 调用在回溯中可见),它调用具有静态局部变量的函数 Foo()。静态局部变量是一个对象,它的构造函数通过多层函数调用,然后突然回溯有几个??,然后在第二个模块B的静态初始化中(__static函数再次出现) ,然后调用 Foo(),但由于 Foo() 从未在本地静态变量上的互斥锁第一次仍然设置时返回,因此它锁定。
一个静态初始化如何触发另一个?我的第一个理论是共享库——模块 A 会调用模块 B 中的某个函数,这会导致模块 B 加载,从而触发 B 的静态初始化,但情况似乎并非如此。模块 A 根本不使用模块 B。所以我有第二个(也是可怕的)猜测。比如说:
模块 A 使用一些模板函数或模板类中的函数,例如
foo<int>::bar()
模块 B 还使用
foo<int>::bar()
模块 A 完全不依赖于模块 B
在链接时,链接器有两个实例
foo<int>::bar()
,但这没关系,因为模板函数被标记为弱符号......在运行时,模块 A 调用
foo<int>::bar
,并且模块 B 的静态初始化被触发,即使模块 B 不依赖于模块 A!为什么?因为链接器决定在链接时使用模块 B 的 foo::bar 实例而不是模块 A 的实例。
这种特殊情况是否有效?或者一个模块的静态初始化不应该在另一个模块中触发静态初始化?
澄清: GCC 自动创建互斥锁以保护任何函数静态变量。我自己没有对互斥锁做任何事情。这是 GCC 使函数静态变量线程安全的方式。
更新:我知道翻译单元之间没有定义静态初始化,我不应该依赖订单。但我很好奇这是否是正常行为作为调试问题的线索。编译器生成执行此操作的代码是否正常,或者它是否可能表明 GCC 中的错误?
java - Java - 静态初始化块内部的类类型
是否可以从静态初始化块中获取类类型?
这是我目前拥有的简化版本:
这更接近我正在做的事情,即初始化一个包含有关对象及其注释等信息的数据结构......也许我使用了错误的模式?
编辑
我根据最适合我的问题的方法选择了公认的答案,但在我看来,当前所有三个答案都有其优点。
c++ - 函数局部静态 const 对象的线程安全初始化
这个问题让我质疑我多年来一直遵循的做法。
对于函数局部静态 const 对象的线程安全初始化,我保护对象的实际构造,但不保护引用它的函数局部引用的初始化。像这样的东西:
这个想法是锁定需要时间,如果引用被多个线程覆盖,那就没关系了。
如果这是我会感兴趣的
- 在实践中足够安全吗?
- 根据规则安全吗?(我知道,当前的标准甚至不知道“并发”是什么,但是践踏已经初始化的引用呢?其他标准,比如 POSIX,是否有与此相关的内容要说?)
我想知道这一点的原因是我想知道我是否可以保留代码原样,或者我是否需要返回并修复它。
对于好奇的头脑:
我使用的许多这样的函数局部静态 const 对象都是在第一次使用时从 const 数组初始化并用于查找的映射。例如,我有一些 XML 解析器,其中标记名称字符串映射到enum
值,因此我可以稍后switch
覆盖标记的enum
值。
由于我得到了一些关于该做什么的答案,但没有得到我实际问题的答案(参见上面的 1. 和 2.),我将对此展开悬赏。再说一遍:
我对我能做什么不感兴趣,我真的很想知道这个。
java - JLS 中是否对执行静态初始化块的顺序有任何保证?
我想知道使用以下结构是否可靠:
是否有可能NullPointerException
因为msgSource
初始化块将在初始化块之前执行engMessages
?
(关于为什么我不在msgSource
上面的 init.block 末尾进行初始化:只是口味问题;如果所描述的结构不可靠,我会这样做)
c++ - 如果析构函数有副作用并且对象是从另一个静态对象的析构函数访问的,如何进行静态反初始化?
有一个简单且众所周知的模式可以避免静态初始化失败,如C++ FAQ Lite 的第 10.13 节所述。
在这个标准模式中,有一个权衡,要么构造的对象永远不会被破坏(如果析构函数没有重要的副作用,这不是问题),要么不能安全地从另一个静态对象的析构函数访问静态对象(请参阅C++ FAQ Lite 的第 10.14 节)。
所以我的问题是:如果静态对象的析构函数具有最终必须发生的重要副作用并且静态对象必须由另一个静态对象的析构函数访问,您如何避免静态反初始化失败?
(注意:FAQ-lite 提到这个问题在C++ 常见问题的 FAQ 16.17 中得到了回答: M. Cline 和 G. Lomow 的常见问题。我无法访问这本书,这就是我问这个问题的原因。 )
c++ - C/C++ 中有什么方法可以检测静态初始化期间代码是否正在运行?
我正在编写一个可用作 DLL 的跟踪库。它基本上被我系统中的每个组件所消耗。一个棘手的要求是跟踪函数需要在进程生命周期的早期调用,甚至在 main() 运行之前。
该库的使用者包括可执行文件、静态链接的 DLL、延迟加载的 DLL 和动态加载的 DLL。所有的变化。
一些跟踪功能在静态初始化中不能很好地发挥作用,但其他的很好。理想情况下,我希望能够在初始化期间为消费者提供最少的安全功能,然后在初始化完成后提供全部功能。
要求消费者自己进行明确的“我完成初始化”调用是行不通的,因为某些消费者本身就是 DLL,并且无法控制托管它们的可执行文件。同样的问题只是将链条上移一级。
我希望有某种方法可以让我询问运行时是否或我当前正在静态初始化中运行,或者该阶段是否已完成。这样的事情可能吗?
更复杂的是,我需要在 5 个平台上运行。我不需要一次写入的解决方案,但我确实需要让它在所有平台上以某种方式工作。