题
我使用静态初始化来简化在 C++ 中向工厂注册某些类的过程。不幸的是,我认为编译器正在优化“未使用”的对象,这些对象旨在在其构造函数中完成有用的工作。有没有办法告诉编译器不要优化全局变量?
class SomeClass {
public:
SomeClass() {
/* do something useful */
}
};
SomeClass instance;
我在 SomeClass 构造函数中的断点没有被命中。在我的实际代码中,SomeClass 位于头文件中,实例位于源文件中,或多或少是单独的。
编辑:正如 KJAWolf 猜测的那样,这段代码实际上被编译成静态库,而不是可执行文件。其目的是使用类型及其创建者的静态列表来注册静态库也提供的一些类型,以便工厂在构造时读取。由于这些类型是随库提供的,因此不希望将此代码添加到可执行文件中。
我还发现,通过将代码移动到包含其他现有代码的另一个源文件,它可以正常工作。似乎是由这些全局对象组成的文件才是导致问题的原因。就好像那个翻译单元被完全忽略了。
解决方案
,编译器是不允许optimiza远全局对象。结果 即使他们从来没有使用过。
其他财产以后是发生在你的代码。结果 现在,如果你建立了一个静态库与您的全局对象和全局对象不是从它不会被拉入链接器可执行文件的可执行文件引用。
其他提示
,编译器不应该优化掉这种全局 - 如果它这样做,它被简单地断裂。
要建立关亚瑟Ulfeldt的,易失性告诉这个变量可以外部改变编译器的知识的编译器。我用它把一个声明,让调试器设置断点。它也是可以改变基于环境或需要特殊序列的硬件寄存器有用。即串行端口接收寄存器和某些看门狗寄存器。
你可以用
#pragma optimize off int globalVar #pragma optimize on
但我不知道这是否只适用于 Visual Studio ( http://msdn.microsoft.com/en-us/library/chh3fb0k(VS.80).aspx ).
您还可以告诉编译器根本不优化,特别是当您正在调试时......
您使用gcc使用gdb?有,在过去的gdb其中不能正确地设定断点的构造的问题。
此外,您使用的优化级别,其允许编译器在类定义内联方法。
您需要连接时使用-whole存档。看到这里的答案:
我有相同的设置&问题上VS2008。
我发现,如果你声明你类dllexport
也不会进行优化。
class __declspec( dllexport ) Cxxx
{
.
}
然而,这产生大量的警告在我的情况下,因为我必须声明在这个类也作为DLLEXPORT使用的所有类。
所有优化是关闭(在调试模式下),仍然这是最优化。也易失性/编译最优化关闭。在此类的创建(在同一CPP文件)全局变量等不工作。
刚刚发现DLLEXPORT要求至少从exe文件包括这些类中的一些其他的cpp文件的头文件!所以,唯一的选择就是增加一个文件,呼吁为每个类的一些静态成员,并将该文件添加到使用这些类的所有项目。
如何使用关键字挥发性?这将阻止编译器过多的优化。