简体   繁体   English

C ++永远不会引用静态类的静态成员。 是否可以确定将其初始化,还是可以从二进制文件中将其省略?

[英]C++ A static member of a static class is never referenced. Will it be initialized for sure or may it be omitted from the binary?

Let's say I have class A with only static members. 假设我的A类只有静态成员。 One of its members is of class B 其成员之一是B级

class A { 
  //...
  static B b;
}

In the A.cpp file I initialize all static members, using their constructors. 在A.cpp文件中,我使用其构造函数初始化所有静态成员。

A.cpp:

B A::b(/*constructor arguments*/);

Now, nowhere in my whole project do I ever use the variable A::b. 现在,在我整个项目的任何地方都没有使用变量A :: b。

Does that mean that the construction of that variable may totally be omitted from the final binary file by the compiler or the linker? 这是否意味着编译器或链接器可以完全从最终二进制文件中忽略该变量的构造?

Even if I never use that variable, its construction has impact to the system configuration. 即使我从未使用过该变量,它的构造也会影响系统配置。 (It may affect peripheral registers for example). (例如,它可能会影响外设寄存器)。

I am not using makefiles. 我没有使用makefile文件。 I am using Atmel studio for AVR uControllers. 我正在将Atmel studio用于AVR uController。

How can I be sure that the constructor of that variable will be executed during the globals and statics initialization phase of my program? 如何确定该变量的构造函数将在程序的全局和静态初始化阶段执行?

And, in general, how can I control that? 而且,一般而言,我该如何控制呢? (There may be a case that I need the opposite: to make sure it doesn't get initialized unless needed somewhere) (在某些情况下,我需要相反的操作:确保除非需要某处,否则不要初始化它)

I have the impression that the initialization code may be omitted by the linker if there is no reference of that name anywhere. 我的印象是,如果在任何地方都没有该名称的引用,则链接器可能会省略初始化代码。

Is that true? 真的吗?

Does it make a difference if other static variables from the file A.cpp are used? 如果使用文件A.cpp中的其他静态变量,是否会有所不同? Maybe it has to do with the automated Makefile creation by the IDE, maybe it omits the whole cpp file if nothing is referenced from within 可能与IDE自动创建Makefile有关,如果在内部未引用任何内容,则可能会忽略整个cpp文件

*The A.cpp belongs to a static library which I include into the project as a .a file * A.cpp属于静态库,我将其作为.a文件包含在项目中

Thanks! 谢谢!

It's a bit complicated, because it depends also on the linker. 这有点复杂,因为它还取决于链接器。

If you are building static libraries lib*.a then it's possible that the object will not be pulled into an executable during linking. 如果要构建静态库lib*.a则在链接期间可能不会将该对象拉入可执行文件。 In this case it will not be run. 在这种情况下,它将不会运行。 see GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()' 请参见GCC C ++链接器错误:对“ vtable for XXX”的未定义引用,对“ ClassName :: ClassName()”的未定义引用

If you use shared libraries or just build an executable then the code will be in the binary. 如果使用共享库或仅构建可执行文件,则代码将在二进制文件中。 Now comes the question of will it be executed. 现在是将要执行的问题。

Whether a static storage duration object is initialized depends a tiny bit on the implementation (there is some leeway to allow for optimization). 静态存储持续时间对象是否初始化取决于实现的一小部分(有一些余地可以进行优化)。 BUT I think most implementations usually do it before main() . 但是我认为大多数实现通常在main()之前执行。 But a static storage duration object must be initialized before any variable or function defined in the same translation unit are used. 但是,在使用同一转换单元中定义的任何变量或函数之前,必须初始化静态存储持续时间对象。 See 6.8.3.3 of the standard for exact legal definition. 有关确切的法律定义,请参见标准的6.8.3.3。 see https://stackoverflow.com/a/1273257/14065 参见https://stackoverflow.com/a/1273257/14065

Now there is also another thing you have to consider. 现在,您还需要考虑另一件事。 All static storage duration objects in a translation unit are constructed in the same order that they are declared within the translation unit (that happen during the dynamic initialization phase). 转换单元中的所有静态存储持续时间对象的构造顺序与它们在转换单元中声明的顺序相同(在动态初始化阶段发生)。 Note: the order across translation units is undefined. 注意:翻译单元之间的顺序是不确定的。 see https://stackoverflow.com/a/211307/14065 参见https://stackoverflow.com/a/211307/14065

Note: There is also a "static initialization" phase that happens prior to "dynamic initialization" phase where all static storage duration objects are zero initialized or are initialized using constant expressions. 注意:还有一个“静态初始化”阶段发生在“动态初始化”阶段之前,在此阶段,所有静态存储持续时间对象都被初始化为零或使用常量表达式初始化。

But because of "Initialization Order Fiasco" (hate that name, it's not a fiasco its well defined you just need to know the rules, but that's the name you should google). 但是由于“ Initialization Order Fiasco”(讨厌这个名字,它并不是一个定义明确的惨败,您只需要了解规则,但这就是您应该在Google上看到的名字)。 You should avoid static storage duration objects at file scope (especially if they reference other static storage variables at file scope). 您应避免在文件范围内使用静态存储持续时间对象(尤其是如果它们在文件范围内引用了其他静态存储变量)。

But there is workaround: Create a static storage duration in a function and return a reference. 但是有一种解决方法:在函数中创建静态存储持续时间并返回引用。 Use the function to get access to the object and that will solve your initialization order issues. 使用该函数可以访问该对象,这将解决您的初始化顺序问题。

Using functions rather than globals: Is access to a static function variable slower than access to a global variable? 使用函数而不是全局变量: 对静态函数变量的访问是否比对全局变量的访问慢?
Solving the order of initialization: https://stackoverflow.com/a/335746/14065 解决初始化的顺序: https : //stackoverflow.com/a/335746/14065

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM