如何防止编译出"未使用的"全局变量?

Ben*_*ers 22 c++ global-variables

我正在使用静态初始化来简化在C++中使用工厂注册某些类的过程.不幸的是,我认为编译器正在优化"未使用的"对象,这些对象旨在在其构造函数中执行有用的工作.有没有办法告诉编译器不要优化全局变量?

class SomeClass {
    public:
        SomeClass() {
            /* do something useful */
        }
};

SomeClass instance;
Run Code Online (Sandbox Code Playgroud)

我在SomeClass的构造函数中的断点没有被击中.在我的实际代码中,SomeClass位于头文件中,实例位于源文件中,或多或少是单独的.

编辑:正如KJAWolf猜测的那样,这段代码实际上被编译成静态库,而不是可执行文件.它的目的是注册静态库提供的一些类型,静态列表类型及其创建者,然后工厂从构造中读取.由于lib提供了这些类型,因此不希望将此代码添加到可执行文件中.

我还发现通过将代码移动到包含其他现有代码的另一个源文件,它可以正常工作.似乎拥有一个纯粹由这些全局对象组成的文件是导致问题的原因.就好像那个翻译单元完全被忽略了一样.

Mar*_*ork 37

不允许编译器优化全局对象.
即使他们从未使用过.

你的代码中还发生了其他事情.
现在,如果您使用全局对象构建了一个静态库,并且未从可执行文件中引用该全局对象,则链接器不会将其拉入可执行文件中.

  • 我赞成这个,因为我认为这是解决真正问题的唯一答案; 正如提问者所说的那样"似乎拥有纯粹由这些全局对象组成的文件是造成问题的原因.就好像那个翻译单元完全被忽略了".翻译单元被忽略,因为链接器将其省略,因为它位于库中.如果一个对象在一个库中并且没有被应用程序中的任何东西调用,那么它就被省略了,这就是库的整个想法! (10认同)

Pav*_*aev 5

编译器永远不应该优化掉这样的全局变量 - 如果它这样做,它就会被破坏.

  • 如果编译器可以检测不使用全局,则可以省略它们.GCC(在此上下文中为G ++)可以并且确实省略了一些变量 - 例如,旧的'在对象文件中嵌入一个版本'技巧不适用于现代GCC - 文件静态值被检测为未使用并优化出对象文件. (3认同)