什么原因导致 TU 被包含在编译中?

问题描述 投票:0回答:3

老实说,我有点超出了我的深度。

我正在做一些相当好奇的实验,让预主函数通过匿名名称空间在工厂中注册我的类。直到最近,将以下内容添加到类定义 (.cpp) 中就可以解决问题。

namespace { int x = Register<classType>(className); }

这将被包装在一个宏中,“注册”会将类型和名称传递给我的工厂。

这工作得很好,包含这个宏的每个类都被注册,直到我将代码移动到静态库中。现在,由于这些类仅由工厂引用,因此看起来它们在构建中被省略了 - 我的“注册”函数不再被调用,因此我的工厂是空的。

我已经设法通过将所有宏移至管理器对象的构造函数中来解决此问题,但我注意到,一旦我在那里引用它们,.cpp 文件中的宏就开始再次被调用。我猜是因为现在这些类实际上被某些东西引用了。

但是,我真的不想这样做,而且我似乎找不到一种非承诺的方式来引用构造函数中的类(例如

class ClassToRegister;
),其中将它们包含在构建中,因此我的注册宏将被调用。

首先,这有道理吗?

其次,关于如何强制这些 TU 进行编译以便匿名命名空间在运行时“启动”,有什么建议吗?

c++ visual-studio-2010 visual-c++ macros
3个回答
1
投票

看来这是使用静态库的重要组成部分;如果没有链接器巫毒,未使用的代码将无法通过。


0
投票

静态库是一堆目标文件,你给链接器说“嘿,在这里找到我在其他地方没有定义的东西”。因此,如果库中给定的目标文件未填充依赖项,则在不依赖链接器的其他功能的情况下,您将无法将其包含在程序中(例如,某些链接器可以包含所有目标文件)静态库,而不仅仅是填充依赖项的库)。


-1
投票

您很可能是积极优化的受害者,但有一个原因:由于您没有在无名命名空间中使用对象,因此编译器会删除它们。

你可以尝试这样出行:

namespace foo
{
namespace{
MACRO_TO_DEFINE_VARIABLE( MyClass ); // define a variable named registrationObj
};

MyClass::MyClass()
{
  (void)registrationObj;
}
}
© www.soinside.com 2019 - 2024. All rights reserved.