问题标签 [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.

0 投票
4 回答
1237 浏览

java - 初始化大量常量时如何规避Java中静态初始化器的大小限制

我有一个类包含大量生成的常量,例如:

当生成的常量数量非常多时,这会导致静态初始化器大于 Java 方法大小的上限(即 > 64kb),从而导致编译器错误。一种解决方案是为可以保证生成少于 64kb 字节码的块创建几个“块初始化方法”,以便它们适合一种方法:

这样做的缺点是我不能再将常量声明为final,因为它们现在不再直接在静态初始化程序中初始化。

我的问题是,如何以仍然可以生成static final常量的方式规避编译器/JVM 限制?

0 投票
1 回答
817 浏览

c++ - 为什么 c++ 类需要在类范围之外定义静态字段(数据成员)?

可能重复:
初始化私有静态成员
为什么我不能在类中初始化非常量静态成员或静态数组?

这对我来说很奇怪。为什么不假设在全局范围内有一个静态字段?

0 投票
4 回答
6247 浏览

c++ - __attribute__((constructor)) 调用顺序混乱

这里的答案表明 __attribute__((constructor)) 不是在静态初始化之后调用的,而是按声明顺序调用的。

那么,如果不保证在所有数据初始化时调用它,它的目的是什么?我们也可以在 Foo 构造函数中包含我们的 ((constructor)) 代码。

我正在寻找的是一种在共享库中拥有在初始化所有静态数据并调用静态构造函数后将执行的代码的方法。我看到人们推荐 __attribute__((constructor)) 作为 DllMain 的替代品;我们可以看到这是错误的,因为一些静态数据可能还没有初始化。

当然,在单个文件(编译单元)中,我们可以安排静态。但是在一个典型的程序中有很多文件。有没有办法保证一个文件中的 ((constructor)) 在共享库中的所有其他静态变量都被初始化后肯定会被调用?

如果我将带有静态初始化(构造函数、对象等)的文件放在 gcc 命令行的末尾:

这个文件的静态构造函数是否保证最后被调用?我进行了实验,当我更改源文件的顺序时,printfs 的顺序发生了变化;但它是否在某处指定并保证在编译系统/计算机中相同?

例如,引用:

在链接时,gcc 驱动程序将 crtbegin.o 放在所有可重定位文件之前,并将 crtend.o 放在所有可重定位文件之后。©

据我了解,上面的引用暗示传递给链接器的 .o 文件的顺序定义了静态初始化的顺序。我对么?

另一个有趣的可能解决方案可能是编写一个 GCC 插件来调整静态初始化(例如,将代码添加到 .ctors 部分等)。但这只是一个想法,也许有人可以扩展。

这里介绍了另一种可能的解决方案。简而言之,可以使用外部构建后工具对可执行文件(库)中的 .ctors 条目进行重新排序。但我不是 ELF 格式的专家;我想知道以这种方式调整 .so 文件是否可行且足够容易。

我感兴趣的是解决一个特定的问题,或者证明它是不可能解决的(至少为什么上面的解决方案不起作用)。

0 投票
1 回答
762 浏览

c++ - 如何保证模板结构中 const 静态成员的初始化顺序

我有两个模板结构,每个都包含一个 const 静态成员变量。这些成员变量之一的初始化取决于第二个。因此,我希望能够保证第二个在第一个之前初始化。这是一个简化的示例:

依赖项.hpp:

测试结构.hpp:

测试.cpp:

main的输出是

也就是说,如果已经为 type 实例化了TestStruct<T>' ,则它staticVar会被正确初始化,但否则它会保持为 0 ,因为尚未初始化。取消注释 [1] 和 [2] 解决了类型问题和(即,所有输出 1.5,即使已注释 [3] 也是如此),但如果可能的话,我宁愿不必列出所有可能的类型或为那些实例化模板键入不使用它们的代码。我希望能够在(或)中放入一些东西来保证已经为该类型实例化,而不必指定 T 可能是什么类型。DependencyTDependency<T>::staticVarfloatdoubleTestStruct<T>testStruct.hppDependency

我看过C++ 静态成员初始化(里面的模板很有趣)如何强制初始化静态成员?. 第一个很好地解释了情况,但没有为像我这样的问题提出解决方案。第二个有两个解决方案,但似乎都不能在 GCC 4.2.1 中工作(或者我错误地应用了它......)。

我应该尝试任何其他技巧或解决方法,还是我坚持显式实例化?

0 投票
2 回答
4374 浏览

c++ - C++ 静态成员初始化与编译器链接相混淆。怎么解决?

我在 c++ 类的这些静态成员初始化方面遇到了麻烦。有关更多信息,请参阅我的代码。

来源

头文件.h

员工.cpp

老板.cpp

主文件

这里有许多不同结果的编译代码:

预编译:

编译、运行和结果:

我想在编译时使用库存档而不是与巨型对象顺序混淆。帮我解决它们。

谢谢你。

0 投票
2 回答
664 浏览

c++ - 本地静态函数对象的初始化是线程安全的吗?

以下两个函数产生不同的程序集,这告诉我它们是不同的。有人能告诉我他们有什么不同吗?func2中的函数局部静态变量初始化是否线程安全?如果答案取决于编译器,我想知道最常见的编译器如何处理 func2。

0 投票
2 回答
1043 浏览

c++ - 时间:2019-05-01 标签:c++static-init-fiascoexample

在 Bruce Eckel 的“Thinking in C++”的帮助下学习 C++,卡在练习 32,第 10 章。问题是如何更改链接顺序,Mirror::test() 调用对象 m5 返回 false。这是我的代码。

镜像.h:

任务

一.cpp

二.cpp

三.cpp

等等。最后,

五.cpp

m5.test() 返回真。任务说,我应该更改链接顺序,m5.test() 返回 false。我曾尝试使用:

init_priority(优先级)

在标准 C++ 中,保证在命名空间范围内定义的对象按照严格按照它们在给定翻译单元中定义的顺序进行初始化。不保证跨翻译单元的初始化。但是,GNU C++ 允许用户通过指定相对优先级来控制在命名空间范围内定义的对象的初始化顺序 init_priority 属性,这是一个当前介于 101 和 65535 之间的常量整数表达式。较低的数字表示较高的优先级。

但没有运气。

完整的练习文本:

在头文件中,创建一个包含两个数据成员的 Mirror 类:一个指向 Mirror 对象的指针和一个 bool。给它两个构造函数:默认构造函数将 bool 初始化为 true,将 Mirror 指针初始化为零。第二个构造函数将指向 Mirror 对象的指针作为参数,并将其分配给对象的内部指针;它将 bool 设置为 false。添加成员函数test():如果对象的指针非零,则返回通过指针调用的test()的值。如果指针为零,则返回布尔值。现在创建五个 cpp 文件,每个文件都包含 Mirror 标头。第一个 cpp 文件使用默认构造函数定义了一个全局 Mirror 对象。第二个文件将第一个文件中的对象声明为extern,并使用第二个构造函数定义了一个全局Mirror对象,带有指向第一个对象的指针。继续这样做,直到到达最后一个文件,该文件也将包含一个全局对象定义。在该文件中,main() 应该调用 test() 函数并报告结果。如果结果为真,请找出如何更改链接器的链接顺序并更改它,直到结果为假。

0 投票
3 回答
1193 浏览

java - 使用静态初始化块来提高性能

假设生产中使用的现有代码库包含一个类 A,该类 A 包含一个方法,该方法使用 setter 填充另一个 POJO 类 B 的 N 个字段并将 POJO 返回给调用者,并且假设类 B 的所有实例将仅在以下方面有所不同两个字段,即 N - 2 个字段在 B 类的所有实例中都是相同的,如果 A 类具有对 B 类的静态引用并初始化 B 类的字段在静态中不变初始化块?这样,在每次调用时填充类 B 的 N 个字段的类 A 中的方法现在只需填充两个不同的字段。这也将消除为每次调用类 A 中的方法创建一个类型 B 的新对象的需要。这种方法在多线程应用程序中的含义是什么?

或者,我们可以将 B 类中所有不会更改的字段声明为静态,以便 A 类中的方法仅设置每次调用更改的字段。无论哪种方式,性能提升是否值得,或者这种变化是否符合过早的优化?

例子 :

0 投票
1 回答
1558 浏览

c++ - c++静态模板成员初始化问题

gcc 4.5.1,SuSE Linux i686

假设我们有以下代码:

在这种情况下,我们在标准输出中不会有任何输出。编译器不会生成代码来初始化 A 类的浮点和双重特化。

但是..如果我们像这样改变初始化:

编译器将生成这样的代码,我们将在输出中包含双“B()”。

有人可以帮助我理解这种行为吗?

0 投票
2 回答
243 浏览

visual-studio-2008 - C++ 静态初始化惨败是否适用于类层次结构?

我在静态初始化中遇到崩溃(调试断言失败:VC++ 2008 中的无效 CRT 堆指针),我不确定我是否理解原因。

我已经阅读了C++ FAQ中有关静态初始化惨败的所有内容,并且我想我已经掌握了它——我不明白为什么会发生这种情况,或者为什么会出现这种惨败。

这就是这种情况(为简洁起见,省略了大多数非静态成员)。我有一个类 A,在 Ah 中定义:

然后,我有一个类 C,它有一个嵌套类 B,它是 A 的子类。C 还包含 B 类型的私有静态成员:

最后是 C 的实现文件 C.cpp,其中包含 my_personal_B 的存储单元:

许多类都重复这种模式,每个类都有一个继承自 A 的嵌套类。通过多次代码修订,这一切都运行得完美无缺,但最近应用程序因以下特定错误消息而崩溃:

调试断言失败!

程序:
[已编辑].exe
文件:f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c
行:1511

表达式:_CrtIsValidHeapPointer(pUserData)

如果单击进行调试,则会在 C.cpp 中显示定义静态成员的行。

这看起来不像是静态惨败,因为没有任何静态引用 my_personal_B,A 和 B 除了默认构造函数之外都没有任何东西,因此不可能引用其他尚未初始化的静态对象。我理解惨败的方式是,当一个静态对象引用另一个尚未初始化的静态对象时,它就发生了。

不过,如果我将静态成员更改为首次使用时初始化的方法,崩溃似乎就消失了。

所以问题是,为什么会崩溃?