何时可以在没有RTTI的情况下编译c ++会导致问题?

McP*_*inM 54 c++ gcc rtti

我正在使用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_casttypeid)使用.如果您不使用该语言的那些部分,则可以使用此标志来节省一些空间.请注意,异常处理使用相同的信息,但会根据需要生成它.该 dynamic_cast运营商仍然可以使用,不需要运行时类型信息广播,即强制转换为void *或以明确的基类.

  • @lurscher,我刚用g ++ 4.2.1检查过它确实会产生错误.我收到以下错误"fnortti.cc:6:错误:'dynamic_cast'不允许使用-fno-rtti". (10认同)
  • 在真正受内存限制的环境中编写时,您只需要使用-fno-rtti,例如嵌入式程序; 现代手机通常有足够的内存,你不需要-fno-rtti,所以你必须使用更小的东西. (6认同)
  • @Lie Ryan:Clang/LLVM在他们的项目中禁用RTTI来擦除内存,但它意味着要在普通计算机上运行.我承认这不是一个典型的项目:) (4认同)

And*_*y G 7

我很感激这篇文章为一个非常古老的问题提供了另一个答案,但我今天遇到了它,并想指出,到目前为止给出的答案在所有方面都不准确。

如果您的代码使用的库本身使用 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)

  • @Amos:异常如何与 RTTI 相关联? (2认同)
  • @VioletGiraffe 他们不是。GCC 文档指出,异常可以在没有 RTTI 的情况下工作 - 任何必要的数据都会根据需要生成。 (2认同)