Clang错误地删除死代码

时间:2015-01-13 17:03:54

标签: c++ macos linker clang++ dead-code

认为这是clang或OSX链接器中的错误,但我想在此问一下确认。

我在C ++程序中有以下(简化)设置。单例存储库类:

class Repository {
public:
    static Repository *instance();
    void registerWidget(const char *name, Widget *w) {}
};

小部件界面:

class Widget {
public:
    virtual void widgetify() = 0;
};

最后一个简单的小部件:

class SimpleWidget : public Widget {
public:
    virtual void widgetify() {}
};

SimpleWidget内部我希望在运行时自动将小部件注册到Repository。通常我使用匿名命名空间和寄存器功能来执行此操作。像这样:

namespace {
    bool registrar() {
        Registrar::instance() -> registerWidget("SimpleWidget", new SimpleWidget);
        return true;
    }

    bool R = registrar();
}

在使用Qt定位iOS和Android的当前项目中,我遇到了此系统的问题。 clang(或链接器)将SimpleWidget标识为死代码并将其剥离(因此它不会显示在Repository中,因为永远不会调用registrar()。)尽管在SimpleWidget中明显引用了registrar(),但似乎仍然这样做了。如果我在任何其他翻译单元中引用SimpleWidget,则SimpleWidget不再被剥离,一切正常。

我是否遗漏了有关死代码剥离应该如何工作的内容,或者这是一个合法的工具链错误?

1 个答案:

答案 0 :(得分:1)

需要在第一次调用该翻译单元(.cpp文件)中的函数之前创建翻译单元(例如R)中的所有对象。您没有在TU中调用单个函数,因此不需要创建R,因此registrar()确实是死代码,而且registrar()专门调用的任何内容都是同样死了。

工具链是正确的。