Wanneer kan het compileren van c++ zonder RTTI problemen veroorzaken?

Ik gebruik de vlag -fno-rttivan gcc om mijn C++ te compileren zonder informatie over het runtime-type.

Ervan uitgaande dat ik dynamic_cast<>of typeid()niet gebruik, is er dan iets dat me tot latere problemen kan leiden?


Antwoord 1, autoriteit 100%

Aangezien uw vraag specifiek is voor GCC, dient u de documentatie voor de versie die u gebruikt zorgvuldig te raadplegen. De documentatie voor GCC 4.5.2 zegt het volgende. Wat uit mijn lezing zou aangeven dat als je dynamic_cast en typeid vermijdt, je in orde zou moeten zijn. Dat gezegd hebbende, ik heb geen persoonlijke ervaring met -fno-rtti. Misschien wil je uitleggen waarom je -fno-rtti gebruikt.

-fno-rtti
Schakel het genereren van informatie over elke klas uit met
virtuele functies voor gebruik door de C++
kenmerken van runtime-type-identificatie
(dynamic_casten typeid). als jij
gebruik die delen van de taal niet,
je kunt wat ruimte besparen door dit te gebruiken
vlag. Houd er rekening mee dat het afhandelen van uitzonderingen
gebruikt dezelfde informatie, maar het zal
genereren als dat nodig is. De
dynamic_castoperator kan nog steeds zijn
gebruikt voor afgietsels die niet nodig zijn:
runtime-type-informatie, d.w.z. casts
naar void *of naar eenduidige basis
lessen.

Er is discussie over de relatie tussen virtuele functies en RTTI beschikbaar op Geen RTTI maar toch virtuele methoden. De korte versie is dat virtuele functies prima zouden moeten werken zonder RTTI.


Antwoord 2, autoriteit 15%

We gebruiken gcc al 5 jaar zonder rtti zonder specifieke problemen (geen dynamic_cast of typeid)


Antwoord 3, autoriteit 2%

Ik stel het op prijs dat ik weer een antwoord op een heel oude vraag plaats, maar ik kwam het vandaag tegen en wil erop wijzen dat de antwoorden die tot nu toe zijn gegeven niet in alle opzichten juist zijn.

Er kan een mogelijk probleem optreden als uw code een bibliotheek gebruikt die zelf RTTI-informatie gebruikt.

De volgende code is hier een eenvoudig voorbeeld van:

#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

Hier hebben we een bibliotheek die een aantal klassen biedt. Het is gecompileerd met RTTI omdat het intern dynamic_castgebruikt, maar we zijn ons hier niet van bewust (we hebben de broncode niet gelezen en het werd niet genoemd in de bibliotheekdocumentatie). De volgende opdracht kan worden gebruikt om de bibliotheek te maken:

g++ -shared -o libmodule.so -fPIC code.cpp -DLIB

We hebben ook onze applicatie. We subclasseren een bibliotheekklasse en geven een instantie hiervan door aan een bibliotheekfunctie. We compileren onze applicatie zonder RTTI omdat we ruimte willen besparen en we houden niet van het feit dat RTTI informatie uitloogt over de namen van onze klassen in onze binaire applicatie. Het uitvoerbare bestand van de toepassing maken dat de bibliotheek gebruikt:

g++ -s -fno-rtti -o app code.cpp -DAPP -L. -lmodule -Wl,-rpath,.

Deze applicatie, gecompileerd met de -fno-rttizal crashen omdat de applicatie geen RTTI-informatie bevat en hoewel het deze zelf niet gebruikt, doet de bibliotheek dat wel.

Als dit een bibliotheek van derden is, is het misschien niet mogelijk om er zeker van te zijn dat deze dynamic_cast niet gebruikt op een manier die uw code kan beïnvloeden. Erger nog, het is misschien niet vandaag, maar het kan in de toekomst worden vervangen door een versie die dat wel doet, waarna de toepassing vervolgensbegint te crashen.

Other episodes