我认为这是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 和注册函数来执行此操作。像这样:
namespace {
    bool registrar() {
        Registrar::instance() -> registerWidget("SimpleWidget", new SimpleWidget);
        return true;
    }

    bool R = registrar();
}

在当前使用针对iOS和Android的Qt的项目中,我遇到了该系统的问题。 clang(或链接程序)正在将SimpleWidget标识为无效代码并将其剥离(因此,由于从不调用Repository,因此它不会显示在registrar()中。)尽管SimpleWidget显然是在registrar()中引用的,但似乎这样做。如果我在其他翻译单元中都引用了SimpleWidget,则SimpleWidget不再被剥离,并且一切正常。

我是否缺少有关死代码剥离应该如何工作的信息,或者这是一个合法的工具链错误?

最佳答案

在首次调用该转换单元(.cpp文件)中的函数之前,需要创建转换单元(例如R)中的所有对象。您在TU中没有对单个函数的调用,因此不需要创建R,因此registrar()确实是无效代码,并且从registrar()专门调用的任何内容也同样无效。

工具链正确。

07-27 13:50