我正在使用gcc的-fno-rtti标志来编译我的C++而没有运行时类型信息.
假设我没有使用dynamic_cast<>或typeid(),有什么东西可以引导我以后出现问题吗?
Bow*_*ens 39
由于您的问题是针对GCC的,因此您应该仔细查阅您正在使用的版本的文档.GCC 4.5.2的文档说明如下.从我的阅读中可以看出,如果你避免使用dynamic_cast和typeid,你应该没问题.也就是说,我没有-fno-rtti的亲身经历.也许您可能想详细说明为什么使用-fno-rtti.
-fno-rtti
禁止使用虚拟函数生成有关每个类的信息,以供C++运行时类型标识功能(dynamic_cast和typeid)使用.如果您不使用该语言的那些部分,则可以使用此标志来节省一些空间.请注意,异常处理使用相同的信息,但会根据需要生成它.该dynamic_cast运营商仍然可以使用,不需要运行时类型信息广播,即强制转换为void *或以明确的基类.
我很感激这篇文章为一个非常古老的问题提供了另一个答案,但我今天遇到了它,并想指出,到目前为止给出的答案在所有方面都不准确。
如果您的代码使用的库本身使用 RTTI 信息,则可能会出现潜在问题。
以下代码是一个简单的示例:
#include <stdio.h>
// Library header
struct A { virtual void fn(); };
struct B : A { virtual void fn(); };
void lib_fn(A* ptr);
// Library code
#ifdef LIB
void A::fn() { puts("a"); }
void B::fn() { puts("b"); }
void lib_fn(A* ptr)
{
if (B* b = dynamic_cast<B*>(ptr))
puts("successful dynamic_cast");
ptr->fn();
}
#endif
// Application code
#ifdef APP
struct C : B
{
virtual void fn()
{ puts("c"); }
};
int main()
{
C obj;
lib_fn(&obj);
return 0;
}
#endif
Run Code Online (Sandbox Code Playgroud)
这里我们有一个提供许多类的库。它是用RTTI编译的,因为它dynamic_cast内部使用,但我们不知道这一点(我们没有阅读源代码,并且库文档中也没有提到)。可以使用以下命令来创建库:
g++ -shared -o libmodule.so -fPIC code.cpp -DLIB
我们也有我们的应用程序。我们对库类进行子类化,并将其实例传递给库函数。我们在不使用 RTTI 的情况下编译应用程序,因为我们希望节省空间,并且我们不喜欢 RTTI 在应用程序二进制文件中泄露有关类名称的信息。要创建使用该库的应用程序可执行文件:
g++ -s -fno-rtti -o app code.cpp -DAPP -L. -lmodule -Wl,-rpath,.
使用 编译的此应用程序-fno-rtti将会崩溃,因为该应用程序不包含 RTTI 信息,即使它本身不使用它,但库会使用它。
如果这是第三方库,则可能无法确定它不会以可能影响您的代码的方式使用dynamic_cast。更糟糕的是,今天可能不会,但将来可能会被替换为具有此功能的版本,此时应用程序将开始崩溃。
小智 5
我们使用没有rtti的gcc 5年没有特定问题(不使用dynamic_cast或typeid)