2009-09-29 53 views
6

如果我在C++中有多个链接的C++静态链接库,如果它们使用不同的启用/禁用运行时间值进行编译,是否可以共享(传入和传出函数)类对象类型信息(RTTI)?在C++中混合使用RTTI标志

- 编辑: 感谢您的回复,我担心的具体事情是 1.是否启用RTTI更改静态(非多态类型)的sizeof行为?

and 2.如果我在支持RTTI的库中创建类并将其传递给另一个不支持RTTI的库,那么虚拟方法是否正常工作。 (反之亦然)

and lastly 3.如果我在支持RTTI的库中创建类,我希望能够使用dynamic_cast,如果我将该对象传递给启用了非RTTI的库,可以我仍然使用的对象。 ......我不会假设,反正这似乎是一个坏主意......我只是好奇。

回答

6

RTTI信息如何存储是一个实现细节,因此不能跨不同编译器移植。

而且大多数编译器甚至不保证标志不同的编译对象将使用相同的ABI因为有方法。这在发布和调试库中最显着,但其他标志也可能会导致差异。

不仅可以在ABI为函数/方法改变,但标志可以影响结构元件之间所使用的编译器。因此,当具有不同的标志编译没有虚拟方法甚至对象可以是不相容的填充。

使用大多数IDS时,您可以看到效果。调试/发布二进制文件被内置到独立目录中,并且仅针对相同种类的二进制文件进行链接(由于标志差异可能导致不兼容,因此任何用户定义的版本都将内置到单独的唯一目录中)。如果您更改构建中的某些标志,那么整个项目通常会被迫重新构建。

+0

这里没有其他人想到的优秀点,特别是有关填充的问题取决于编译器设置。 – Elemental 2009-09-29 16:00:33

+0

@Loki Astari:是否暗示如果我使用.so或.dll中的对象(禁用RTTI进行编译),我将无法使用dynamic_cast,也不能为该对象使用typeid。或者更糟糕的是,ABI不正确,所以程序不兼容(可能是崩溃等)。 – 2012-09-12 00:07:55

+0

@ Shao-ChuanWang:潜在的。这一切都取决于你的编译器。为了安全起见,所有对象必须使用完全相同的标志进行编译。 – 2012-09-12 00:30:57

1

这取决于你在说什么特定的C++编译器 - 我近期没有真正的跨平台C++经验(近年来我的C++工作几乎完全用Linux上的C++),但几年以前我敢打赌,gcc会允许你逃避相当多的这样的混混,Visual C++“没有办法”,其他编译器有点在中间...!)

0

只要类共享不是多态(即,他们不包含虚函数),这不会是一个问题。但是,您将无法使用dynamic_cast,禁用RTTI的typeid和例外。

+0

不同的标志可能会导致结构中的填充不同,从而导致对象跨库不兼容。 – 2009-09-29 10:48:20